home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 242 / Issue 242 - April 2008 - DPCS0408DVD.ISO / Open Source / AutoHotKey / Source / AutoHotkey104705_source.exe / source / script_expression.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2007-07-30  |  209.1 KB  |  3,217 lines

  1. /*
  2. AutoHotkey
  3.  
  4. Copyright 2003-2007 Chris Mallett (support@autohotkey.com)
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15. */
  16.  
  17. //////////////////////////////////////////////////////////////////////////////////////
  18. // v1.0.40.02: This is now a separate file to allow its compiler optimization settings
  19. // to be set independently of those of the other modules.  In one benchmark, this
  20. // improved performance of expressions and function calls by 9% (that is, when the
  21. // other modules are set to "minmize size" such as for the AutoHotkeySC.bin file).
  22. // This gain in performance is at the cost of a 1.5 KB increase in the size of the
  23. // compressed code, which seems well worth it given how often expressions and
  24. // function-calls are used (such as in loops).
  25. //
  26. // ExpandArgs() and related functions were also put into this file because that
  27. // further improves performance across the board -- even for AutoHotkey.exe despite
  28. // the fact that the only thing that changed for it was the module move, not the
  29. // compiler settings.  Apparently, the butterfly effect can cause even minor
  30. // modifications to impact the overall performance of the generated code by as much as
  31. // 7%.  However, this might have more to do with cache hits and misses in the CPU than
  32. // with the nature of the code produced by the compiler.
  33. // UPDATE 10/18/2006: There's not much difference anymore -- in fact, using min size
  34. // for everything makes compiled scripts slightly faster in basic benchmarks, probably
  35. // due to the recent addition of the linker optimization that physically orders
  36. // functions in a better order inside the EXE.  Therefore, script_expression.cpp no
  37. // longer has a separate "favor fast code" option.
  38. //////////////////////////////////////////////////////////////////////////////////////
  39.  
  40. #include "stdafx.h" // pre-compiled headers
  41. #include "script.h"
  42. #include "globaldata.h" // for a lot of things
  43. #include "qmath.h" // For ExpandExpression()
  44.  
  45. // __forceinline: Decided against it for this function because alhough it's only called by one caller,
  46. // testing shows that it wastes stack space (room for its automatic variables would be unconditionally 
  47. // reserved in the stack of its caller).  Also, the performance benefit of inlining this is too slight.
  48. // Here's a simple way to verify wasted stack space in a caller that calls an inlined function:
  49. //    DWORD stack
  50. //    _asm mov stack, esp
  51. //    MsgBox(stack);
  52. char *Line::ExpandExpression(int aArgIndex, ResultType &aResult, char *&aTarget, char *&aDerefBuf
  53.     , size_t &aDerefBufSize, char *aArgDeref[], size_t aExtraSize)
  54. // Caller should ignore aResult unless this function returns NULL.
  55. // Returns a pointer to this expression's result, which can be one of the following:
  56. // 1) NULL, in which case aResult will be either FAIL or EARLY_EXIT to indicate the means by which the current
  57. //    quasi-thread was terminated as a result of a function call.
  58. // 2) The constant empty string (""), in which case we do not alter aTarget for our caller.
  59. // 3) Some persistent location not in aDerefBuf, namely the mContents of a variable or a literal string/number,
  60. //    such as a function-call that returns "abc", 123, or a variable.
  61. // 4) At position aTarget inside aDerefBuf (note that aDerefBuf might have been reallocated by us).
  62. // aTarget is left unchnaged except in case #4, in which case aTarget has been adjusted to the position after our
  63. // result-string's terminator.  In addition, in case #4, aDerefBuf, aDerefBufSize, and aArgDeref[] have been adjusted
  64. // for our caller if aDerefBuf was too small and needed to be enlarged.
  65. //
  66. // Thanks to Joost Mulders for providing the expression evaluation code upon which this function is based.
  67. {
  68.     char *target = aTarget; // "target" is used to track our usage (current position) within the aTarget buffer.
  69.  
  70.     // The following must be defined early so that mem_count is initialized and the array is guaranteed to be
  71.     // "in scope" in case of early "goto" (goto substantially boosts performance and reduces code size here).
  72.     #define MAX_EXPR_MEM_ITEMS 200 // v1.0.47.01: Raised from 100 because a line consisting entirely of concat operators can exceed it.  However, there's probably not much point to going much above MAX_TOKENS/2 because then it would reach the MAX_TOKENS limit first.
  73.     char *mem[MAX_EXPR_MEM_ITEMS]; // No init necessary.  In most cases, it will never be used.
  74.     int mem_count = 0; // The actual number of items in use in the above array.
  75.     char *result_to_return = ""; // By contrast, NULL is used to tell the caller to abort the current thread.  That isn't done for normal syntax errors, just critical conditions such as out-of-memory.
  76.     Var *output_var = (mActionType == ACT_ASSIGNEXPR) ? OUTPUT_VAR : NULL; // Resolve early because it's similar in usage/scope to the above.  Plus MUST be resolved prior to calling any script-functions since they could change the values in sArgVar[].
  77.  
  78.     // Having a precedence array is required at least for SYM_POWER (since the order of evaluation
  79.     // of something like 2**1**2 does matter).  It also helps performance by avoiding unnecessary pushing
  80.     // and popping of operators to the stack. This array must be kept in sync with "enum SymbolType".
  81.     // Also, dimensioning explicitly by SYM_COUNT helps enforce that at compile-time:
  82.     static UCHAR sPrecedence[SYM_COUNT] =  // Performance: UCHAR vs. INT benches a little faster, perhaps due to the slight reduction in code size it causes.
  83.     {
  84.         0,0,0,0,0,0,0    // SYM_STRING, SYM_INTEGER, SYM_FLOAT, SYM_VAR, SYM_OPERAND, SYM_DYNAMIC, SYM_BEGIN (SYM_BEGIN must be lowest precedence).
  85.         , 82, 82         // SYM_POST_INCREMENT, SYM_POST_DECREMENT: Highest precedence operator so that it will work even though it comes *after* a variable name (unlike other unaries, which come before).
  86.         , 4, 4           // SYM_CPAREN, SYM_OPAREN (to simplify the code, parentheses must be lower than all operators in precedence).
  87.         , 6              // SYM_COMMA -- Must be just above SYM_OPAREN so it doesn't pop OPARENs off the stack.
  88.         , 7,7,7,7,7,7,7,7,7,7,7,7  // SYM_ASSIGN_*. THESE HAVE AN ODD NUMBER to indicate right-to-left evaluation order, which is necessary for cascading assignments such as x:=y:=1 to work.
  89. //        , 8              // THIS VALUE MUST BE LEFT UNUSED so that the one above can be promoted to it by the infix-to-postfix routine.
  90.         , 11, 11         // SYM_IFF_ELSE, SYM_IFF_THEN (ternary conditional).  HAS AN ODD NUMBER to indicate right-to-left evaluation order, which is necessary for ternaries to perform traditionally when nested in each other without parentheses.
  91. //        , 12             // THIS VALUE MUST BE LEFT UNUSED so that the one above can be promoted to it by the infix-to-postfix routine.
  92.         , 16             // SYM_OR
  93.         , 20             // SYM_AND
  94.         , 25             // SYM_LOWNOT (the word "NOT": the low precedence version of logical-not).  HAS AN ODD NUMBER to indicate right-to-left evaluation order so that things like "not not var" are supports (which can be used to convert a variable into a pure 1/0 boolean value).
  95. //        , 26             // THIS VALUE MUST BE LEFT UNUSED so that the one above can be promoted to it by the infix-to-postfix routine.
  96.         , 30, 30, 30     // SYM_EQUAL, SYM_EQUALCASE, SYM_NOTEQUAL (lower prec. than the below so that "x < 5 = var" means "result of comparison is the boolean value in var".
  97.         , 34, 34, 34, 34 // SYM_GT, SYM_LT, SYM_GTOE, SYM_LTOE
  98.         , 38             // SYM_CONCAT
  99.         , 42             // SYM_BITOR -- Seems more intuitive to have these three higher in prec. than the above, unlike C and Perl, but like Python.
  100.         , 46             // SYM_BITXOR
  101.         , 50             // SYM_BITAND
  102.         , 54, 54         // SYM_BITSHIFTLEFT, SYM_BITSHIFTRIGHT
  103.         , 58, 58         // SYM_ADD, SYM_SUBTRACT
  104.         , 62, 62, 62     // SYM_MULTIPLY, SYM_DIVIDE, SYM_FLOORDIVIDE
  105.         , 67,67,67,67,67 // SYM_NEGATIVE (unary minus), SYM_HIGHNOT (the high precedence "!" operator), SYM_BITNOT, SYM_ADDRESS, SYM_DEREF
  106.         // NOTE: THE ABOVE MUST BE AN ODD NUMBER to indicate right-to-left evaluation order, which was added in v1.0.46 to support consecutive unary operators such as !*var !!var (!!var can be used to convert a value into a pure 1/0 boolean).
  107. //        , 68             // THIS VALUE MUST BE LEFT UNUSED so that the one above can be promoted to it by the infix-to-postfix routine.
  108.         , 72             // SYM_POWER (see note below).  Associativity kept as left-to-right for backward compatibility (e.g. 2**2**3 is 4**3=64 not 2**8=256).
  109.         , 77, 77         // SYM_PRE_INCREMENT, SYM_PRE_DECREMENT (higher precedence than SYM_POWER because it doesn't make sense to evaluate power first because that would cause ++/-- to fail due to operating on a non-lvalue.
  110. //        , 78             // THIS VALUE MUST BE LEFT UNUSED so that the one above can be promoted to it by the infix-to-postfix routine.
  111. //        , 82, 82         // RESERVED FOR SYM_POST_INCREMENT, SYM_POST_DECREMENT (which are listed higher above for the performance of YIELDS_AN_OPERAND().
  112.         , 86             // SYM_FUNC -- Must be of highest precedence so that it stays tightly bound together as though it's a single operand for use by other operators.
  113.     };
  114.     // Most programming languages give exponentiation a higher precedence than unary minus and logical-not.
  115.     // For example, -2**2 is evaluated as -(2**2), not (-2)**2 (the latter is unsupported by qmathPow anyway).
  116.     // However, this rule requires a small workaround in the postfix-builder to allow 2**-2 to be
  117.     // evaluated as 2**(-2) rather than being seen as an error.  v1.0.45: A similar thing is required
  118.     // to allow the following to work: 2**!1, 2**not 0, 2**~0xFFFFFFFE, 2**&x.
  119.     // On a related note, the right-to-left tradition of something like 2**3**4 is not implemented (maybe in v2).
  120.     // Instead, the expression is evaluated from left-to-right (like other operators) to simplify the code.
  121.  
  122.     #define MAX_TOKENS 512 // Max number of operators/operands.  Seems enough to handle anything realistic, while conserving call-stack space.
  123.     ExprTokenType infix[MAX_TOKENS], *postfix[MAX_TOKENS], *stack[MAX_TOKENS + 1];  // +1 for SYM_BEGIN on the stack.
  124.     int infix_count = 0, postfix_count = 0, stack_count = 0;
  125.     // Above dimensions the stack to be as large as the infix/postfix arrays to cover worst-case
  126.     // scenarios and avoid having to check for overflow.  For the infix-to-postfix conversion, the
  127.     // stack must be large enough to hold a malformed expression consisting entirely of operators
  128.     // (though other checks might prevent this).  It must also be large enough for use by the final
  129.     // expression evaluation phase, the worst case of which is unknown but certainly not larger
  130.     // than MAX_TOKENS.
  131.  
  132.     ///////////////////////////////////////////////////////////////////////////////////////////////
  133.     // TOKENIZE THE INFIX EXPRESSION INTO AN INFIX ARRAY: Avoids the performance overhead of having
  134.     // to re-detect whether each symbol is an operand vs. operator at multiple stages.
  135.     ///////////////////////////////////////////////////////////////////////////////////////////////
  136.     // In v1.0.46.01, this section was simplified to avoid transcribing the entire expression into the
  137.     // deref buffer.  In addition to improving performance and reducing code size, this also solves
  138.     // obscure timing bugs caused by functions that have side-effects, especially in comma-separated
  139.     // sub-expressions.  In these cases, one part of an expression could change a built-in variable
  140.     // (indirectly or in the case of Clipboard, directly), an environment variable, or a double-def.
  141.     // For example the dynamic components of a double-deref can be changed by other parts of an
  142.     // expression, even one without commas.  Another example is: fn(clipboard, func_that_changes_clip()).
  143.     // So now, built-in & environment variables and double-derefs are resolve when they're actually
  144.     // encountered during the final/evaluation phase.
  145.     // Another benefit to deferring the resolution of these types of items is that they become eligible
  146.     // for short-circuiting, which further helps performance (they're quite similar to built-in
  147.     // functions in this respect).
  148.     char *op_end, *cp;
  149.     DerefType *deref, *this_deref, *deref_start, *deref_alloca;
  150.     int derefs_in_this_double;
  151.     int cp1; // int vs. char benchmarks slightly faster, and is slightly smaller in code size.
  152.  
  153.     for (cp = mArg[aArgIndex].text, deref = mArg[aArgIndex].deref // Start at the begining of this arg's text and look for the next deref.
  154.         ;; ++deref, ++infix_count) // FOR EACH DEREF IN AN ARG:
  155.     {
  156.         this_deref = deref && deref->marker ? deref : NULL; // A deref with a NULL marker terminates the list (i.e. the final deref isn't a deref, merely a terminator of sorts.
  157.  
  158.         // BEFORE PROCESSING "this_deref" ITSELF, MUST FIRST PROCESS ANY LITERAL/RAW TEXT THAT LIES TO ITS LEFT.
  159.         if (this_deref && cp < this_deref->marker // There's literal/raw text to the left of the next deref.
  160.             || !this_deref && *cp) // ...or there's no next deref, but there's some literal raw text remaining to be processed.
  161.         {
  162.             for (;; ++infix_count) // FOR EACH TOKEN INSIDE THIS RAW/LITERAL TEXT SECTION.
  163.             {
  164.                 // Because neither the postfix array nor the stack can ever wind up with more tokens than were
  165.                 // contained in the original infix array, only the infix array need be checked for overflow:
  166.                 if (infix_count > MAX_TOKENS - 1) // No room for this operator or operand to be added.
  167.                     goto abnormal_end;
  168.  
  169.                 // Only spaces and tabs are considered whitespace, leaving newlines and other whitespace characters
  170.                 // for possible future use:
  171.                 cp = omit_leading_whitespace(cp);
  172.                 if (!*cp // Very end of expression...
  173.                     || this_deref && cp >= this_deref->marker) // ...or no more literal/raw text left to process at the left side of this_deref.
  174.                     break; // Break out of inner loop so that bottom of the outer loop will process this_deref itself.
  175.  
  176.                 ExprTokenType &this_infix_item = infix[infix_count]; // Might help reduce code size since it's referenced many places below.
  177.  
  178.                 // CHECK IF THIS CHARACTER IS AN OPERATOR.
  179.                 cp1 = cp[1]; // Improves performance by nearly 5% and appreciably reduces code size (at the expense of being less maintainable).
  180.                 switch (*cp)
  181.                 {
  182.                 // The most common cases are kept up top to enhance performance if switch() is implemented as if-else ladder.
  183.                 case '+':
  184.                     if (cp1 == '=')
  185.                     {
  186.                         ++cp; // An additional increment to have loop skip over the operator's second symbol.
  187.                         this_infix_item.symbol = SYM_ASSIGN_ADD;
  188.                     }
  189.                     else
  190.                     {
  191.                         if (infix_count && YIELDS_AN_OPERAND(infix[infix_count - 1].symbol))
  192.                         {
  193.                             if (cp1 == '+')
  194.                             {
  195.                                 // For consistency, assume that since the previous item is an operand (even if it's
  196.                                 // ')'), this is a post-op that applies to that operand.  For example, the following
  197.                                 // are all treated the same for consistency (implicit concatention where the '.'
  198.                                 // is omitted is rare anyway).
  199.                                 // x++ y
  200.                                 // x ++ y
  201.                                 // x ++y
  202.                                 // The following implicit concat is deliberately unsupported:
  203.                                 //    "string" ++x
  204.                                 // The ++ above is seen as applying to the string because it doesn't seem worth
  205.                                 // the complexity to distinguish between expressions that can accept a post-op
  206.                                 // and those that can't (operands other than variables can have a post-op;
  207.                                 // e.g. (x:=y)++).
  208.                                 ++cp; // An additional increment to have loop skip over the operator's second symbol.
  209.                                 this_infix_item.symbol = SYM_POST_INCREMENT;
  210.                             }
  211.                             else
  212.                                 this_infix_item.symbol = SYM_ADD;
  213.                         }
  214.                         else if (cp1 == '+') // Pre-increment.
  215.                         {
  216.                             ++cp; // An additional increment to have loop skip over the operator's second symbol.
  217.                             this_infix_item.symbol = SYM_PRE_INCREMENT;
  218.                         }
  219.                         else // Remove unary pluses from consideration since they do not change the calculation.
  220.                             --infix_count; // Counteract the loop's increment.
  221.                     }
  222.                     break;
  223.                 case '-':
  224.                     if (cp1 == '=')
  225.                     {
  226.                         ++cp; // An additional increment to have loop skip over the operator's second symbol.
  227.                         this_infix_item.symbol = SYM_ASSIGN_SUBTRACT;
  228.                         break;
  229.                     }
  230.                     // Otherwise (since above didn't "break"):
  231.                     // Must allow consecutive unary minuses because otherwise, the following example
  232.                     // would not work correctly when y contains a negative value: var := 3 * -y
  233.                     if (infix_count && YIELDS_AN_OPERAND(infix[infix_count - 1].symbol))
  234.                     {
  235.                         if (cp1 == '-')
  236.                         {
  237.                             // See comments at SYM_POST_INCREMENT about this section.
  238.                             ++cp; // An additional increment to have loop skip over the operator's second symbol.
  239.                             this_infix_item.symbol = SYM_POST_DECREMENT;
  240.                         }
  241.                         else
  242.                             this_infix_item.symbol = SYM_SUBTRACT;
  243.                     }
  244.                     else if (cp1 == '-') // Pre-decrement.
  245.                     {
  246.                         ++cp; // An additional increment to have loop skip over the operator's second symbol.
  247.                         this_infix_item.symbol = SYM_PRE_DECREMENT;
  248.                     }
  249.                     else // Unary minus.
  250.                     {
  251.                         // Set default for cases where the processing below this line doesn't determine
  252.                         // it's a negative numeric literal:
  253.                         this_infix_item.symbol = SYM_NEGATIVE;
  254.                         // v1.0.40.06: The smallest signed 64-bit number (-0x8000000000000000) wasn't properly
  255.                         // supported in previous versions because its unary minus was being seen as an operator,
  256.                         // and thus the raw number was being passed as a positive to _atoi64() or _strtoi64(),
  257.                         // neither of which would recognize it as a valid value.  To correct this, a unary
  258.                         // minus followed by a raw numeric literal is now treated as a single literal number
  259.                         // rather than unary minus operator followed by a positive number.
  260.                         //
  261.                         // To be a valid "literal negative number", the character immediately following
  262.                         // the unary minus must not be:
  263.                         // 1) Whitespace (atoi() and such don't support it, nor is it at all conventional).
  264.                         // 2) An open-parenthesis such as the one in -(x).
  265.                         // 3) Another unary minus or operator such as --x (which is the pre-decrement operator).
  266.                         // To cover the above and possibly other unforeseen things, insist that the first
  267.                         // character be a digit (even a hex literal must start with 0).
  268.                         if ((cp1 >= '0' && cp1 <= '9') || cp1 == '.') // v1.0.46.01: Recognize dot too, to support numbers like -.5.
  269.                         {
  270.                             for (op_end = cp + 2; !strchr(EXPR_OPERAND_TERMINATORS, *op_end); ++op_end); // Find the end of this number (can be '\0').
  271.                             // 1.0.46.11: Due to obscurity, no changes have been made here to support scientific
  272.                             // notation followed by the power operator; e.g. -1.0e+1**5.
  273.                             if (!this_deref || op_end < this_deref->marker) // Detect numeric double derefs such as one created via "12%i% = value".
  274.                             {
  275.                                 // Because the power operator takes precedence over unary minus, don't collapse
  276.                                 // unary minus into a literal numeric literal if the number is immediately
  277.                                 // followed by the power operator.  This is correct behavior even for
  278.                                 // -0x8000000000000000 because -0x8000000000000000**2 would in fact be undefined
  279.                                 // because ** is higher precedence than unary minus and +0x8000000000000000 is
  280.                                 // beyond the signed 64-bit range.  SEE ALSO the comments higher above.
  281.                                 // Use a temp variable because numeric_literal requires that op_end be set properly:
  282.                                 char *pow_temp = omit_leading_whitespace(op_end);
  283.                                 if (!(pow_temp[0] == '*' && pow_temp[1] == '*'))
  284.                                     goto numeric_literal; // Goto is used for performance and also as a patch to minimize the chance of breaking other things via redesign.
  285.                                 //else it's followed by pow.  Since pow is higher precedence than unary minus,
  286.                                 // leave this unary minus as an operator so that it will take effect after the pow.
  287.                             }
  288.                             //else possible double deref, so leave this unary minus as an operator.
  289.                         }
  290.                     } // Unary minus.
  291.                     break;
  292.                 case ',':
  293.                     this_infix_item.symbol = SYM_COMMA; // Used to separate sub-statements and function parameters.
  294.                     break;
  295.                 case '/':
  296.                     if (cp1 == '=')
  297.                     {
  298.                         ++cp; // An additional increment to have loop skip over the operator's second symbol.
  299.                         this_infix_item.symbol = SYM_ASSIGN_DIVIDE;
  300.                     }
  301.                     else if (cp1 == '/')
  302.                     {
  303.                         if (cp[2] == '=')
  304.                         {
  305.                             cp += 2; // An additional increment to have loop skip over the operator's 2nd & 3rd symbols.
  306.                             this_infix_item.symbol = SYM_ASSIGN_FLOORDIVIDE;
  307.                         }
  308.                         else
  309.                         {
  310.                             ++cp; // An additional increment to have loop skip over the second '/' too.
  311.                             this_infix_item.symbol = SYM_FLOORDIVIDE;
  312.                         }
  313.                     }
  314.                     else
  315.                         this_infix_item.symbol = SYM_DIVIDE;
  316.                     break;
  317.                 case '*':
  318.                     if (cp1 == '=')
  319.                     {
  320.                         ++cp; // An additional increment to have loop skip over the operator's second symbol.
  321.                         this_infix_item.symbol = SYM_ASSIGN_MULTIPLY;
  322.                     }
  323.                     else
  324.                     {
  325.                         if (cp1 == '*') // Python, Perl, and other languages also use ** for power.
  326.                         {
  327.                             ++cp; // An additional increment to have loop skip over the second '*' too.
  328.                             this_infix_item.symbol = SYM_POWER;
  329.                         }
  330.                         else
  331.                         {
  332.                             // Differentiate between unary dereference (*) and the "multiply" operator:
  333.                             // See '-' above for more details:
  334.                             this_infix_item.symbol = (infix_count && YIELDS_AN_OPERAND(infix[infix_count - 1].symbol))
  335.                                 ? SYM_MULTIPLY : SYM_DEREF;
  336.                         }
  337.                     }
  338.                     break;
  339.                 case '!':
  340.                     if (cp1 == '=') // i.e. != is synonymous with <>, which is also already supported by legacy.
  341.                     {
  342.                         ++cp; // An additional increment to have loop skip over the '=' too.
  343.                         this_infix_item.symbol = SYM_NOTEQUAL;
  344.                     }
  345.                     else
  346.                         // If what lies to its left is a CPARAN or OPERAND, SYM_CONCAT is not auto-inserted because:
  347.                         // 1) Allows ! and ~ to potentially be overloaded to become binary and unary operators in the future.
  348.                         // 2) Keeps the behavior consistent with unary minus, which could never auto-concat since it would
  349.                         //    always be seen as the binary subtract operator in such cases.
  350.                         // 3) Simplifies the code.
  351.                         this_infix_item.symbol = SYM_HIGHNOT; // High-precedence counterpart of the word "not".
  352.                     break;
  353.                 case '(':
  354.                     // The below should not hurt any future type-casting feature because the type-cast can be checked
  355.                     // for prior to checking the below.  For example, if what immediately follows the open-paren is
  356.                     // the string "int)", this symbol is not open-paren at all but instead the unary type-cast-to-int
  357.                     // operator.
  358.                     if (infix_count && YIELDS_AN_OPERAND(infix[infix_count - 1].symbol)) // If it's an operand, at this stage it can only be SYM_OPERAND or SYM_STRING.
  359.                     {
  360.                         if (infix_count > MAX_TOKENS - 2) // -2 to ensure room for this operator and the operand further below.
  361.                             goto abnormal_end;
  362.                         this_infix_item.symbol = SYM_CONCAT;
  363.                         ++infix_count;
  364.                     }
  365.                     infix[infix_count].symbol = SYM_OPAREN; // MUST NOT REFER TO this_infix_item IN CASE ABOVE DID ++infix_count.
  366.                     break;
  367.                 case ')':
  368.                     this_infix_item.symbol = SYM_CPAREN;
  369.                     break;
  370.                 case '=':
  371.                     if (cp1 == '=')
  372.                     {
  373.                         ++cp; // An additional increment to have loop skip over the other '=' too.
  374.                         this_infix_item.symbol = SYM_EQUALCASE;
  375.                     }
  376.                     else
  377.                         this_infix_item.symbol = SYM_EQUAL;
  378.                     break;
  379.                 case '>':
  380.                     switch (cp1)
  381.                     {
  382.                     case '=':
  383.                         ++cp; // An additional increment to have loop skip over the '=' too.
  384.                         this_infix_item.symbol = SYM_GTOE;
  385.                         break;
  386.                     case '>':
  387.                         if (cp[2] == '=')
  388.                         {
  389.                             cp += 2; // An additional increment to have loop skip over the operator's 2nd & 3rd symbols.
  390.                             this_infix_item.symbol = SYM_ASSIGN_BITSHIFTRIGHT;
  391.                         }
  392.                         else
  393.                         {
  394.                             ++cp; // An additional increment to have loop skip over the second '>' too.
  395.                             this_infix_item.symbol = SYM_BITSHIFTRIGHT;
  396.                         }
  397.                         break;
  398.                     default:
  399.                         this_infix_item.symbol = SYM_GT;
  400.                     }
  401.                     break;
  402.                 case '<':
  403.                     switch (cp1)
  404.                     {
  405.                     case '=':
  406.                         ++cp; // An additional increment to have loop skip over the '=' too.
  407.                         this_infix_item.symbol = SYM_LTOE;
  408.                         break;
  409.                     case '>':
  410.                         ++cp; // An additional increment to have loop skip over the '>' too.
  411.                         this_infix_item.symbol = SYM_NOTEQUAL;
  412.                         break;
  413.                     case '<':
  414.                         if (cp[2] == '=')
  415.                         {
  416.                             cp += 2; // An additional increment to have loop skip over the operator's 2nd & 3rd symbols.
  417.                             this_infix_item.symbol = SYM_ASSIGN_BITSHIFTLEFT;
  418.                         }
  419.                         else
  420.                         {
  421.                             ++cp; // An additional increment to have loop skip over the second '<' too.
  422.                             this_infix_item.symbol = SYM_BITSHIFTLEFT;
  423.                         }
  424.                         break;
  425.                     default:
  426.                         this_infix_item.symbol = SYM_LT;
  427.                     }
  428.                     break;
  429.                 case '&':
  430.                     if (cp1 == '&')
  431.                     {
  432.                         ++cp; // An additional increment to have loop skip over the second '&' too.
  433.                         this_infix_item.symbol = SYM_AND;
  434.                     }
  435.                     else if (cp1 == '=')
  436.                     {
  437.                         ++cp; // An additional increment to have loop skip over the operator's second symbol.
  438.                         this_infix_item.symbol = SYM_ASSIGN_BITAND;
  439.                     }
  440.                     else
  441.                     {
  442.                         // Differentiate between unary "take the address of" and the "bitwise and" operator:
  443.                         // See '-' above for more details:
  444.                         this_infix_item.symbol = (infix_count && YIELDS_AN_OPERAND(infix[infix_count - 1].symbol))
  445.                             ? SYM_BITAND : SYM_ADDRESS;
  446.                     }
  447.                     break;
  448.                 case '|':
  449.                     if (cp1 == '|')
  450.                     {
  451.                         ++cp; // An additional increment to have loop skip over the second '|' too.
  452.                         this_infix_item.symbol = SYM_OR;
  453.                     }
  454.                     else if (cp1 == '=')
  455.                     {
  456.                         ++cp; // An additional increment to have loop skip over the operator's second symbol.
  457.                         this_infix_item.symbol = SYM_ASSIGN_BITOR;
  458.                     }
  459.                     else
  460.                         this_infix_item.symbol = SYM_BITOR;
  461.                     break;
  462.                 case '^':
  463.                     if (cp1 == '=')
  464.                     {
  465.                         ++cp; // An additional increment to have loop skip over the operator's second symbol.
  466.                         this_infix_item.symbol = SYM_ASSIGN_BITXOR;
  467.                     }
  468.                     else
  469.                         this_infix_item.symbol = SYM_BITXOR;
  470.                     break;
  471.                 case '~':
  472.                     // If what lies to its left is a CPARAN or OPERAND, SYM_CONCAT is not auto-inserted because:
  473.                     // 1) Allows ! and ~ to potentially be overloaded to become binary and unary operators in the future.
  474.                     // 2) Keeps the behavior consistent with unary minus, which could never auto-concat since it would
  475.                     //    always be seen as the binary subtract operator in such cases.
  476.                     // 3) Simplifies the code.
  477.                     this_infix_item.symbol = SYM_BITNOT;
  478.                     break;
  479.                 case '?':
  480.                     this_infix_item.symbol = SYM_IFF_THEN;
  481.                     break;
  482.                 case ':':
  483.                     if (cp1 == '=')
  484.                     {
  485.                         ++cp; // An additional increment to have loop skip over the second '|' too.
  486.                         this_infix_item.symbol = SYM_ASSIGN;
  487.                     }
  488.                     else
  489.                         this_infix_item.symbol = SYM_IFF_ELSE;
  490.                     break;
  491.  
  492.                 case '"': // QUOTED/LITERAL STRING.
  493.                     // Note that single and double-derefs are impossible inside string-literals
  494.                     // because the load-time deref parser would never detect anything inside
  495.                     // of quotes -- even non-escaped percent signs -- as derefs.
  496.                     if (infix_count && YIELDS_AN_OPERAND(infix[infix_count - 1].symbol)) // If it's an operand, at this stage it can only be SYM_OPERAND or SYM_STRING.
  497.                     {
  498.                         if (infix_count > MAX_TOKENS - 2) // -2 to ensure room for this operator and the operand further below.
  499.                             goto abnormal_end;
  500.                         this_infix_item.symbol = SYM_CONCAT;
  501.                         ++infix_count;
  502.                     }
  503.                     // MUST NOT REFER TO this_infix_item IN CASE ABOVE DID ++infix_count:
  504.                     infix[infix_count].symbol = SYM_STRING; // Marked explicitly as string vs. SYM_OPERAND to prevent it from being seen as a number, e.g. if (var == "12.0") would be false if var contains "12" with no trailing ".0".
  505.                     infix[infix_count].marker = target; // Point it to its position in the buffer (populated below).
  506.                     // The following section is nearly identical to one in DefineFunc().
  507.                     // Find the end of this string literal, noting that a pair of double quotes is
  508.                     // a literal double quote inside the string:
  509.                     for (++cp;;) // Omit the starting-quote from consideration, and from the resulting/built string.
  510.                     {
  511.                         if (!*cp) // No matching end-quote. Probably impossible due to load-time validation.
  512.                             goto abnormal_end;
  513.                         if (*cp == '"') // And if it's not followed immediately by another, this is the end of it.
  514.                         {
  515.                             ++cp;
  516.                             if (*cp != '"') // String terminator or some non-quote character.
  517.                                 break;  // The previous char is the ending quote.
  518.                             //else a pair of quotes, which resolves to a single literal quote. So fall through
  519.                             // to the below, which will copy of quote character to the buffer. Then this pair
  520.                             // is skipped over and the loop continues until the real end-quote is found.
  521.                         }
  522.                         //else some character other than '\0' or '"'.
  523.                         *target++ = *cp++;
  524.                     }
  525.                     *target++ = '\0'; // Terminate it in the buffer.
  526.                     continue; // Continue vs. break to avoid the ++cp at the bottom. Above has already set cp to be the character after this literal string's close-quote.
  527.  
  528.                 default: // NUMERIC-LITERAL, DOUBLE-DEREF, RELATIONAL OPERATOR SUCH AS "NOT", OR UNRECOGNIZED SYMBOL.
  529.                     if (*cp == '.') // This one must be done here rather than as a "case".  See comment below.
  530.                     {
  531.                         if (cp1 == '=')
  532.                         {
  533.                             ++cp; // An additional increment to have loop skip over the operator's second symbol.
  534.                             this_infix_item.symbol = SYM_ASSIGN_CONCAT;
  535.                             break;
  536.                         }
  537.                         if (IS_SPACE_OR_TAB(cp1))
  538.                         {
  539.                             this_infix_item.symbol = SYM_CONCAT;
  540.                             break;
  541.                         }
  542.                         //else this is a '.' that isn't followed by a space, tab, or '='.  So it's probably
  543.                         // a number without a leading zero like .2, so continue on below to process it.
  544.                     }
  545.  
  546.                     // Find the end of this operand or keyword, even if that end extended into the next deref.
  547.                     // StrChrAny() is not used because if *op_end is '\0', the strchr() below will find it too:
  548.                     for (op_end = cp + 1; !strchr(EXPR_OPERAND_TERMINATORS, *op_end); ++op_end);
  549.                     // Now op_end marks the end of this operand or keyword.  That end might be the zero terminator
  550.                     // or the next operator in the expression, or just a whitespace.
  551.                     if (this_deref && op_end >= this_deref->marker)
  552.                         goto double_deref; // This also serves to break out of the inner for(), equivalent to a break.
  553.                     // Otherwise, this operand is a normal raw numeric-literal or a word-operator (and/or/not).
  554.                     // The section below is very similar to the one used at load-time to recognize and/or/not,
  555.                     // so it should be maintained with that section.  UPDATE for v1.0.45: The load-time parser
  556.                     // now resolves "OR" to || and "AND" to && to improve runtime performance and reduce code size here.
  557.                     // However, "NOT" but still be parsed here at runtime because it's not quite the same as the "!"
  558.                     // operator (different precedence), and it seemed too much trouble to invent some special
  559.                     // operator symbol for load-time to insert as a placeholder/substitute (especially since that
  560.                     // symbol would appear in ListLines).
  561.                     if (op_end-cp == 3
  562.                         && (cp[0] == 'n' || cp[0] == 'N')
  563.                         && (  cp1 == 'o' ||   cp1 == 'O')
  564.                         && (cp[2] == 't' || cp[2] == 'T')) // "NOT" was found.
  565.                     {
  566.                         this_infix_item.symbol = SYM_LOWNOT;
  567.                         cp = op_end; // Have the loop process whatever lies at op_end and beyond.
  568.                         continue; // Continue vs. break to avoid the ++cp at the bottom (though it might not matter in this case).
  569.                     }
  570. numeric_literal:
  571.                     // Since above didn't "continue", this item is probably a raw numeric literal (either SYM_FLOAT
  572.                     // or SYM_INTEGER, to be differentiated later) because just about every other possibility has
  573.                     // been ruled out above.  For example, unrecognized symbols should be impossible at this stage
  574.                     // because load-time validation would have caught them.  And any kind of unquoted alphanumeric
  575.                     // characters (other than "NOT", which was detected above) wouldn't have reached this point
  576.                     // because load-time pre-parsing would have marked it as a deref/var, not raw/literal text.
  577.                     if (   toupper(op_end[-1]) == 'E' // v1.0.46.11: It looks like scientific notation...
  578.                         && !(cp[0] == '0' && toupper(cp[1]) == 'X') // ...and it's not a hex number (this check avoids falsely detecting hex numbers that end in 'E' as exponents). This line fixed in v1.0.46.12.
  579.                         && !(cp[0] == '-' && cp[1] == '0' && toupper(cp[2]) == 'X') // ...and it's not a negative hex number (this check avoids falsely detecting hex numbers that end in 'E' as exponents). This line added as a fix in v1.0.47.03.
  580.                         )
  581.                     {
  582.                         // Since op_end[-1] is the 'E' or an exponent, the only valid things for op_end[0] to be
  583.                         // are + or - (it can't be a digit because the loop above would never have stopped op_end
  584.                         // at a digit).  If it isn't + or -, it's some kind of syntax error, so doing the following
  585.                         // seems harmless in any case:
  586.                         do // Skip over the sign and its exponent; e.g. the "+1" in "1.0e+1".  There must be a sign in this particular sci-notation number or we would never have arrived here.
  587.                             ++op_end;
  588.                         while (*op_end >= '0' && *op_end <= '9'); // Avoid isdigit() because it sometimes causes a debug assertion failure at: (unsigned)(c + 1) <= 256 (probably only in debug mode), and maybe only when bad data got in it due to some other bug.
  589.                     }
  590.                     if (infix_count && YIELDS_AN_OPERAND(infix[infix_count - 1].symbol)) // If it's an operand, at this stage it can only be SYM_OPERAND or SYM_STRING.
  591.                     {
  592.                         if (infix_count > MAX_TOKENS - 2) // -2 to ensure room for this operator and the operand further below.
  593.                             goto abnormal_end;
  594.                         this_infix_item.symbol = SYM_CONCAT;
  595.                         ++infix_count;
  596.                     }
  597.                     // MUST NOT REFER TO this_infix_item IN CASE ABOVE DID ++infix_count:
  598.                     infix[infix_count].symbol = SYM_OPERAND;
  599.                     infix[infix_count].marker = target; // Point it to its position in the buffer (populated below).
  600.                     memcpy(target, cp, op_end - cp);
  601.                     target += op_end - cp;
  602.                     *target++ = '\0'; // Terminate it in the buffer.
  603.                     cp = op_end; // Have the loop process whatever lies at op_end and beyond.
  604.                     continue; // "Continue" to avoid the ++cp at the bottom.
  605.                 } // switch() for type of symbol/operand.
  606.                 ++cp; // i.e. increment only if a "continue" wasn't encountered somewhere above. Although maintainability is reduced to do this here, it avoids dozens of ++cp in other places.
  607.             } // for each token in this section of raw/literal text.
  608.         } // End of processing of raw/literal text (such as operators) that lie to the left of this_deref.
  609.  
  610.         if (!this_deref) // All done because the above just processed all the raw/literal text (if any) that
  611.             break;       // lay to the right of the last deref.
  612.  
  613.         // THE ABOVE HAS NOW PROCESSED ANY/ALL RAW/LITERAL TEXT THAT LIES TO THE LEFT OF this_deref.
  614.         // SO NOW PROCESS THIS_DEREF ITSELF.
  615.         if (infix_count > MAX_TOKENS - 1) // No room for the deref item below to be added.
  616.             goto abnormal_end;
  617.         DerefType &this_deref_ref = *this_deref; // Boosts performance slightly.
  618.         if (this_deref_ref.is_function) // Above has ensured that at this stage, this_deref!=NULL.
  619.         {
  620.             if (infix_count && YIELDS_AN_OPERAND(infix[infix_count - 1].symbol)) // If it's an operand, at this stage it can only be SYM_OPERAND or SYM_STRING.
  621.             {
  622.                 if (infix_count > MAX_TOKENS - 2) // -2 to ensure room for this operator and the operand further below.
  623.                     goto abnormal_end;
  624.                 infix[infix_count++].symbol = SYM_CONCAT;
  625.             }
  626.             infix[infix_count].symbol = SYM_FUNC;
  627.             infix[infix_count].deref = deref;
  628.         }
  629.         else // this_deref is a variable.
  630.         {
  631.             if (*this_deref_ref.marker == g_DerefChar) // A double-deref because normal derefs don't start with '%'.
  632.             {
  633.                 // Find the end of this operand, even if that end extended into the next deref.
  634.                 // StrChrAny() is not used because if *op_end is '\0', the strchr() below will find it too:
  635.                 for (op_end = this_deref_ref.marker + this_deref_ref.length; !strchr(EXPR_OPERAND_TERMINATORS, *op_end); ++op_end);
  636.                 goto double_deref;
  637.             }
  638.             else
  639.             {
  640.                 if (infix_count && YIELDS_AN_OPERAND(infix[infix_count - 1].symbol)) // If it's an operand, at this stage it can only be SYM_OPERAND or SYM_STRING.
  641.                 {
  642.                     if (infix_count > MAX_TOKENS - 2) // -2 to ensure room for this operator and the operand further below.
  643.                         goto abnormal_end;
  644.                     infix[infix_count++].symbol = SYM_CONCAT;
  645.                 }
  646.                 if (this_deref_ref.var->Type() == VAR_NORMAL // VAR_ALIAS is taken into account (and resolved) by Type().
  647.                     && (g_NoEnv || this_deref_ref.var->Length())) // v1.0.43.08: Added g_NoEnv.  Relies on short-circuit boolean order.
  648.                     // "!this_deref_ref.var->Get()" isn't checked here.  See comments in SYM_DYNAMIC evaluation.
  649.                 {
  650.                     // DllCall() and possibly others rely on this having been done to support changing the
  651.                     // value of a parameter (similar to by-ref).
  652.                     infix[infix_count].symbol = SYM_VAR; // Type() is always VAR_NORMAL as verified above. This is relied upon in several places such as built-in functions.
  653.                 }
  654.                 else // It's either a built-in variable (including clipboard) OR a possible environment variable.
  655.                 {
  656.                     infix[infix_count].symbol = SYM_DYNAMIC;
  657.                     infix[infix_count].buf = NULL; // SYM_DYNAMIC requires that buf be set to NULL for vars (since there are two different types of SYM_DYNAMIC).
  658.                 }
  659.                 infix[infix_count].var = this_deref_ref.var;
  660.             }
  661.         } // Handling of the var or function in this_deref.
  662.  
  663.         // Finally, jump over the dereference text. Note that in the case of an expression, there might not
  664.         // be any percent signs within the text of the dereference, e.g. x + y, not %x% + %y% (unless they're
  665.         // deliberately double-derefs).
  666.         cp += this_deref_ref.length;
  667.         // The outer loop will now do ++infix for us.
  668.  
  669. continue;     // To avoid falling into the label below. The label below is only reached by explicit goto.
  670. double_deref: // Caller has set cp to be start and op_end to be the character after the last one of the double deref.
  671.         if (infix_count && YIELDS_AN_OPERAND(infix[infix_count - 1].symbol)) // If it's an operand, at this stage it can only be SYM_OPERAND or SYM_STRING.
  672.         {
  673.             if (infix_count > MAX_TOKENS - 2) // -2 to ensure room for this operator and the operand further below.
  674.                 goto abnormal_end;
  675.             infix[infix_count++].symbol = SYM_CONCAT;
  676.         }
  677.  
  678.         infix[infix_count].symbol = SYM_DYNAMIC;
  679.         infix[infix_count].buf = target; // Point it to its position in the buffer (populated below).
  680.         memcpy(target, cp, op_end - cp); // "target" is incremented and string-terminated later below.
  681.  
  682.         // Set "deref" properly for the loop to resume processing at the item after this double deref.
  683.         // Callers of double_deref have ensured that deref!=NULL and deref->marker!=NULL (because it
  684.         // doesn't make sense to have a double-deref unless caller discovered the first deref that
  685.         // belongs to this double deref, such as the "i" in Array%i%).
  686.         for (deref_start = deref, ++deref; deref->marker && deref->marker < op_end; ++deref);
  687.         derefs_in_this_double = (int)(deref - deref_start);
  688.         --deref; // Compensate for the outer loop's ++deref.
  689.  
  690.         // There's insufficient room to shoehorn all the necessary data into the token (since circuit_token probably
  691.         // can't be safely overloaded at this stage), so allocate a little bit of stack memory, just enough for the
  692.         // number of derefs (variables) whose contents comprise the name of this double-deref variable (typically
  693.         // there's only one; e.g. the "i" in Array%i%).
  694.         deref_alloca = (DerefType *)_alloca((derefs_in_this_double + 1) * sizeof(DerefType)); // Provides one extra at the end as a terminator.
  695.         memcpy(deref_alloca, deref_start, derefs_in_this_double * sizeof(DerefType));
  696.         deref_alloca[derefs_in_this_double].marker = NULL; // Put a NULL in the last item, which terminates the array.
  697.         for (deref_start = deref_alloca; deref_start->marker; ++deref_start)
  698.             deref_start->marker = target + (deref_start->marker - cp); // Point each to its position in the *new* buf.
  699.         infix[infix_count].var = (Var *)deref_alloca; // Postfix evaluation uses this to build the variable's name dynamically.
  700.  
  701.         target += op_end - cp; // Must be done only after the above, since it uses the old value of target.
  702.         *target++ = '\0'; // Terminate the name, which looks something like "Array%i%".
  703.         cp = op_end; // Must be done only after above is done using cp: Set things up for the next iteration.
  704.         // The outer loop will now do ++infix for us.
  705.     } // For each deref in this expression, and also for the final literal/raw text to the right of the last deref.
  706.  
  707.     // Terminate the array with a special item.  This allows infix-to-postfix conversion to do a faster
  708.     // traversal of the infix array.
  709.     if (infix_count > MAX_TOKENS - 1) // No room for the following symbol to be added.
  710.         goto abnormal_end;
  711.     infix[infix_count].symbol = SYM_INVALID;
  712.  
  713.     ////////////////////////////
  714.     // CONVERT INFIX TO POSTFIX.
  715.     ////////////////////////////
  716.     #define STACK_PUSH(token_ptr) stack[stack_count++] = token_ptr
  717.     #define STACK_POP stack[--stack_count]  // To be used as the r-value for an assignment.
  718.     // SYM_BEGIN is the first item to go on the stack.  It's a flag to indicate that conversion to postfix has begun:
  719.     ExprTokenType token_begin;
  720.     token_begin.symbol = SYM_BEGIN;
  721.     STACK_PUSH(&token_begin);
  722.  
  723.     SymbolType stack_symbol, infix_symbol, sym_prev;
  724.     ExprTokenType *fwd_infix, *this_infix = infix;
  725.     int functions_on_stack = 0;
  726.  
  727.     for (;;) // While SYM_BEGIN is still on the stack, continue iterating.
  728.     {
  729.         ExprTokenType *&this_postfix = postfix[postfix_count]; // Resolve early, especially for use by "goto". Reduces code size a bit, though it doesn't measurably help performance.
  730.         infix_symbol = this_infix->symbol;                     //
  731.         stack_symbol = stack[stack_count - 1]->symbol; // Frequently used, so resolve only once to help performance.
  732.  
  733.         // Put operands into the postfix array immediately, then move on to the next infix item:
  734.         if (IS_OPERAND(infix_symbol)) // At this stage, operands consist of only SYM_OPERAND and SYM_STRING.
  735.         {
  736.             if (infix_symbol == SYM_DYNAMIC && SYM_DYNAMIC_IS_VAR_NORMAL_OR_CLIP(this_infix)) // Ordered for short-circuit performance.
  737.             {
  738.                 // v1.0.46.01: If an environment variable is being used as an lvalue -- regardless
  739.                 // of whether that variable is blank in the environment -- treat it as a normal
  740.                 // variable instead.  This is because most people would want that, and also because
  741.                 // it's tranditional not to directly support assignments to environment variables
  742.                 // (only EnvSet can do that, mostly for code simplicity).  In addition, things like
  743.                 // EnvVar.="string" and EnvVar+=2 aren't supported due to obscurity/rarity (instead,
  744.                 // such expressions treat EnvVar as blank). In light of all this, convert environment
  745.                 // variables that are targets of ANY assignments into normal variables so that they
  746.                 // can be seen as a valid lvalues when the time comes to do the assignment.
  747.                 // IMPORTANT: VAR_CLIPBOARD is made into SYM_VAR here, but only for assignments.
  748.                 // This allows built-in functions and other places in the code to treat SYM_VAR
  749.                 // as though it's always VAR_NORMAL, which reduces code size and improves maintainability.
  750.                 sym_prev = this_infix[1].symbol; // Resolve to help macro's code size and performance.
  751.                 if (IS_ASSIGNMENT_OR_POST_OP(sym_prev) // Post-op must be checked for VAR_CLIPBOARD (by contrast, it seems unnecessary to check it for others; see comments below).
  752.                     || stack_symbol == SYM_PRE_INCREMENT || stack_symbol == SYM_PRE_DECREMENT) // Stack *not* infix.
  753.                     this_infix->symbol = SYM_VAR; // Convert clipboard or environment variable into SYM_VAR.
  754.                 // POST-INC/DEC: It seems unnecessary to check for these except for VAR_CLIPBOARD because
  755.                 // those assignments (and indeed any assignment other than .= and :=) will have no effect
  756.                 // on a ON A SYM_DYNAMIC environment variable.  This is because by definition, such
  757.                 // variables have an empty Var::Contents(), and AutoHotkey v1 does not allow
  758.                 // math operations on blank variables.  Thus, the result of doing a math-assignment
  759.                 // operation on a blank lvalue is almost the same as doing it on an invalid lvalue.
  760.                 // The main difference is that with the exception of post-inc/dec, assignments
  761.                 // wouldn't produce an lvalue unless we explicitly check for them all above.
  762.                 // An lvalue should be produced so that the following features are consistent
  763.                 // even for variables whose names happen to match those of environment variables:
  764.                 // - Pass an assignment byref or takes its address; e.g. &(++x).
  765.                 // - Cascading assigments; e.g. (++var) += 4 (rare to be sure).
  766.                 // - Possibly other lvalue behaviors that rely on SYM_VAR being present.
  767.                 // Above logic might not be perfect because it doesn't check for parens such as (var):=x,
  768.                 // and possibly other obscure types of assignments.  However, it seems adequate given
  769.                 // the rarity of such things and also because env vars are being phased out (scripts can
  770.                 // use #NoEnv to avoid all such issues).
  771.             }
  772.             this_postfix = this_infix++;
  773.             this_postfix->circuit_token = NULL; // Set default. It's only ever overridden after it's in the postfix array.
  774.             ++postfix_count;
  775.             continue; // Doing a goto to a hypothetical "standard_postfix_circuit_token" (in lieu of these last 3 lines) reduced performance and didn't help code size.
  776.         }
  777.  
  778.         // Since above didn't "continue", the current infix symbol is not an operand, but an operator or other symbol.
  779.  
  780.         switch(infix_symbol)
  781.         {
  782.         case SYM_CPAREN: // Listed first for performance. It occurs frequently while emptying the stack to search for the matching open-parenthesis.
  783.             if (stack_symbol == SYM_OPAREN) // See comments near the bottom of this case.  The first open-paren on the stack must be the one that goes with this close-paren.
  784.             {
  785.                 --stack_count; // Remove this open-paren from the stack, since it is now complete.
  786.                 ++this_infix;  // Since this pair of parentheses is done, move on to the next token in the infix expression.
  787.                 // There should be no danger of stack underflow in the following because SYM_BEGIN always
  788.                 // exists at the bottom of the stack:
  789.                 if (stack[stack_count - 1]->symbol == SYM_FUNC) // i.e. topmost item on stack is SYM_FUNC.
  790.                 {
  791.                     --functions_on_stack;
  792.                     goto standard_pop_into_postfix; // Within the postfix list, a function-call should always immediately follow its params.
  793.                 }
  794.             }
  795.             else if (stack_symbol == SYM_BEGIN) // Paren is closed without having been opened (currently impossible due to load-time balancing, but kept for completeness).
  796.                 goto abnormal_end; 
  797.             else // This stack item is an operator.
  798.             {
  799.                 goto standard_pop_into_postfix;
  800.                 // By not incrementing i, the loop will continue to encounter SYM_CPAREN and thus
  801.                 // continue to pop things off the stack until the corresponding OPAREN is reached.
  802.             }
  803.             break;
  804.  
  805.         case SYM_FUNC:
  806.             ++functions_on_stack; // This technique performs well but prevents multi-statements from being nested inside function calls (seems too obscure to worry about); e.g. fn((x:=5, y+=3), 2)
  807.             STACK_PUSH(this_infix++);
  808.             // NOW FALL INTO THE OPEN-PAREN BELOW because load-time validation has ensured that each SYM_FUNC
  809.             // is followed by a '('.
  810. // ABOVE CASE FALLS INTO BELOW.
  811.         case SYM_OPAREN:
  812.             // Open-parentheses always go on the stack to await their matching close-parentheses.
  813.             STACK_PUSH(this_infix++);
  814.             break;
  815.  
  816.         case SYM_IFF_ELSE: // i.e. this infix symbol is ':'.
  817.             if (stack_symbol == SYM_BEGIN) // ELSE with no matching IF/THEN (load-time currently doesn't validate/detect this).
  818.                 goto abnormal_end;  // Below relies on the above check having been done, to avoid underflow.
  819.             // Otherwise:
  820.             this_postfix = STACK_POP; // There should be no danger of stack underflow in the following because SYM_BEGIN always exists at the bottom of the stack.
  821.             if (stack_symbol == SYM_IFF_THEN) // See comments near the bottom of this case. The first found "THEN" on the stack must be the one that goes with this "ELSE".
  822.             {
  823.                 this_postfix->circuit_token = this_infix; // Point this "THEN" to its "ELSE" for use by short-circuit. This simplifies short-circuit by means such as avoiding the need to take notice of nested IFF's when discarding a branch (a different stage points the IFF's condition to its "THEN").
  824.                 STACK_PUSH(this_infix++); // Push the ELSE onto the stack so that its operands will go into the postfix array before it.
  825.                 // Above also does ++i since this ELSE found its matching IF/THEN, so it's time to move on to the next token in the infix expression.
  826.             }
  827.             else // This stack item is an operator INCLUDE some other THEN's ELSE (all such ELSE's should be purged from the stack so that 1 ? 1 ? 2 : 3 : 4 creates postfix 112?3:?4: not something like 112?3?4::.
  828.             {
  829.                 this_postfix->circuit_token = NULL; // Set default. It's only ever overridden after it's in the postfix array.
  830.                 // By not incrementing i, the loop will continue to encounter SYM_IFF_ELSE and thus
  831.                 // continue to pop things off the stack until the corresponding SYM_IFF_THEN is reached.
  832.             }
  833.             ++postfix_count;
  834.             break;
  835.  
  836.         case SYM_INVALID:
  837.             if (stack_symbol == SYM_BEGIN) // Stack is basically empty, so stop the loop.
  838.             {
  839.                 --stack_count; // Remove SYM_BEGIN from the stack, leaving the stack empty for use in postfix eval.
  840.                 goto end_of_infix_to_postfix; // Both infix and stack have been fully processed, so move on to the postfix evaluation phase.
  841.             }
  842.             else if (stack_symbol == SYM_OPAREN) // Open paren is never closed (currently impossible due to load-time balancing, but kept for completeness).
  843.                 goto abnormal_end;
  844.             else // Pop item off the stack, AND CONTINUE ITERATING, which will hit this line until stack is empty.
  845.                 goto standard_pop_into_postfix;
  846.             // ALL PATHS ABOVE must continue or goto.
  847.  
  848.         default: // This infix symbol is an operator, so act according to its precedence.
  849.             // If the symbol waiting on the stack has a lower precedence than the current symbol, push the
  850.             // current symbol onto the stack so that it will be processed sooner than the waiting one.
  851.             // Otherwise, pop waiting items off the stack (by means of i not being incremented) until their
  852.             // precedence falls below the current item's precedence, or the stack is emptied.
  853.             // Note: BEGIN and OPAREN are the lowest precedence items ever to appear on the stack (CPAREN
  854.             // never goes on the stack, so can't be encountered there).
  855.             if (   sPrecedence[stack_symbol] < sPrecedence[infix_symbol] + (sPrecedence[infix_symbol] % 2) // Performance: An sPrecedence2[] array could be made in lieu of the extra add+indexing+modulo, but it benched only 0.3% faster, so the extra code size it caused didn't seem worth it.
  856.                 || IS_ASSIGNMENT_EXCEPT_POST_AND_PRE(infix_symbol) && stack_symbol != SYM_DEREF // See note 1 below. Ordered for short-circuit performance.
  857.                 || stack_symbol == SYM_POWER && (infix_symbol >= SYM_NEGATIVE && infix_symbol <= SYM_DEREF // See note 2 below. Check lower bound first for short-circuit performance.
  858.                     || infix_symbol == SYM_LOWNOT)   )
  859.             {
  860.                 // NOTE 1: v1.0.46: The IS_ASSIGNMENT_EXCEPT_POST_AND_PRE line above was added in conjunction with
  861.                 // the new assignment operators (e.g. := and +=). Here's what it does: Normally, the assignment
  862.                 // operators have the lowest precedence of all (except for commas) because things that lie
  863.                 // to the *right* of them in the infix expression should be evaluated first to be stored
  864.                 // as the assignment's result.  However, if what lies to the *left* of the assignment
  865.                 // operator isn't a valid lvalue/variable (and not even a unary like -x can produce an lvalue
  866.                 // because they're not supposed to alter the contents of the variable), obeying the normal
  867.                 // precedence rules would be produce a syntax error due to "assigning to non-lvalue".
  868.                 // So instead, apply any pending operator on the stack (which lies to the left of the lvalue
  869.                 // in the infix expression) *after* the assignment by leaving it on the stack.  For example,
  870.                 // C++ and probably other langauges (but not the older ANSI C) evaluate "true ? x:=1 : y:=1"
  871.                 // as a pair of assignments rather than as who-knows-what (probably a syntax error if you
  872.                 // strictly followed precedence).  Similarly, C++ evaluates "true ? var1 : var2 := 3" not as
  873.                 // "(true ? var1 : var2) := 3" (like ANSI C) but as "true ? var1 : (var2 := 3)".  Other examples:
  874.                 // -> not var:=5 ; It's evaluated contrary to precedence as: not (var:=5) [PHP does this too,
  875.                 //    and probably others]
  876.                 // -> 5 + var+=5 ; It's evaluated contrary to precedence as: 5 + (var+=5) [not sure if other
  877.                 //    languages do ones like this]
  878.                 // -> ++i := 5 ; Silly since increment has no lasting effect; so assign the 5 then do the pre-inc.
  879.                 // -> ++i /= 5 ; Valid, but maybe too obscure and inconsistent to treat it differently than
  880.                 //    the others (especially since not many people will remember that unlike i++, ++i produces
  881.                 //    an lvalue); so divide by 5 then do the increment.
  882.                 // -> i++ := 5 (and i++ /= 5) ; Postfix operator can't produce an lvalue, so do the assignment
  883.                 //    first and then the postfix op.
  884.                 // SYM_DEREF is the only exception to the above because there's a slight chance that
  885.                 // *Var:=X (evaluated strictly according to precedence as (*Var):=X) will be used for someday.
  886.                 // Also, SYM_FUNC seems unaffected by any of this due to its enclosing parentheses (i.e. even
  887.                 // if a function-call can someday generate an lvalue [SYM_VAR], the current rules probably
  888.                 // already support it.
  889.                 // Performance: Adding the above behavior reduced the expressions benchmark by only 0.6%; so
  890.                 // it seems worth it.
  891.                 //
  892.                 // NOTE 2: The SYM_POWER line above is a workaround to allow 2**-2 (and others in v1.0.45) to be
  893.                 // evaluated as 2**(-2) rather than being seen as an error.  However, as of v1.0.46, consecutive
  894.                 // unary operators are supported via the right-to-left evaluation flag above (formerly, consecutive
  895.                 // unaries produced a failure [blank value]).  For example:
  896.                 // !!x  ; Useful to convert a blank value into a zero for use with unitialized variables.
  897.                 // not not x  ; Same as above.
  898.                 // Other examples: !-x, -!x, !&x, -&Var, ~&Var
  899.                 // And these deref ones (which worked even before v1.0.46 by different means: giving
  900.                 // '*' a higher precedence than the other unaries): !*Var, -*Var and ~*Var
  901.                 // !x  ; Supported even if X contains a negative number, since x is recognized as an isolated operand and not something containing unary minus.
  902.                 //
  903.                 // To facilitate short-circuit boolean evaluation, right before an AND/OR/IFF is pushed onto the
  904.                 // stack, point the end of it's left branch to it.  Note that the following postfix token
  905.                 // can itself be of type AND/OR/IFF, a simple example of which is "if (true and true and true)",
  906.                 // in which the first and's parent (in an imaginary tree) is the second "and".
  907.                 // But how is it certain that this is the final operator or operand of and AND/OR/IFF's left branch?
  908.                 // Here is the explanation:
  909.                 // Everything higher precedence than the AND/OR/IFF came off the stack right before it, resulting in
  910.                 // what must be a balanced/complete sub-postfix-expression in and of itself (unless the expression
  911.                 // has a syntax error, which is caught in various places).  Because it's complete, during the
  912.                 // postfix evaluation phase, that sub-expression will result in a new operand for the stack,
  913.                 // which must then be the left side of the AND/OR/IFF because the right side immediately follows it
  914.                 // within the postfix array, which in turn is immediately followed its operator (namely AND/OR/IFF).
  915.                 // Also, the final result of an IFF's condition-branch must point to the IFF/THEN symbol itself
  916.                 // because that's the means by which the condition is merely "checked" rather than becoming an
  917.                 // operand itself.
  918.                 if (infix_symbol <= SYM_AND && infix_symbol >= SYM_IFF_THEN && postfix_count) // Check upper bound first for short-circuit performance.
  919.                     postfix[postfix_count - 1]->circuit_token = this_infix; // In the case of IFF, this points the final result of the IFF's condition to its SYM_IFF_THEN (a different stage points the THEN to its ELSE).
  920.                 if (infix_symbol != SYM_COMMA)
  921.                     STACK_PUSH(this_infix);
  922.                 else // infix_symbol == SYM_COMMA, but which type of comma (function vs. statement-separator).
  923.                 {
  924.                     // KNOWN LIMITATION: Although the functions_on_stack method is simple and efficient, it isn't
  925.                     // capable of detecting commas that separate statements inside a function call such as:
  926.                     //    fn(x, (y:=2, fn2()))
  927.                     // Thus, such attempts will cause the expression as a whole to fail and evaluate to ""
  928.                     // (though individual parts of the expression may execute before it fails).
  929.                     // C++ and possibly other C-like languages seem to allow such expressions as shown by the
  930.                     // following simple example: MsgBox((1, 2)); // In which MsgBox sees (1, 2) as a single arg.
  931.                     // Perhaps this could be solved someday by checking/tracking whether there is a non-function
  932.                     // open-paren on the stack above/prior to the first function-call-open-paren on the stack.
  933.                     // That rule seems flexible enough to work even for things like f1((f2(), X)).  Perhaps a
  934.                     // simple stack traversal could be done to find the first OPAREN.  If it's a function's OPAREN,
  935.                     // this is a function-comma.  Otherwise, this comma is a statement-separator nested inside a
  936.                     // function call.  But the performance impact of that doesn't seem worth it given rarity of use.
  937.                     if (!functions_on_stack) // This comma separates statements rather than function parameters.
  938.                     {
  939.                         STACK_PUSH(this_infix);
  940.                         // v1.0.46.01: Treat ", var = expr" as though the "=" is ":=", even if there's a ternary
  941.                         // on the right side (for consistency and since such a ternary would be stand-alone,
  942.                         // which is a rare use for ternary).  Also cascade to the right to treat things like
  943.                         // x=y=z as assignments because its intuitiveness seems to outweigh other considerations.
  944.                         // In a future version, these transformations could be done at loadtime to improve runtime
  945.                         // performance; but currently that seems more complex than it's worth (and loadtime
  946.                         // performance and code size shouldn't be entirely ignored).
  947.                         for (fwd_infix = this_infix + 1;; fwd_infix += 2)
  948.                         {
  949.                             // The following is checked first to simplify things and avoid any chance of reading
  950.                             // beyond the last item in the array. This relies on the fact that a SYM_INVALID token
  951.                             // exists at the end of the array as a terminator.
  952.                             if (fwd_infix->symbol == SYM_INVALID || fwd_infix[1].symbol != SYM_EQUAL) // Relies on short-circuit boolean order.
  953.                                 break; // No further checking needed because there's no qualified equal-sign.
  954.                             // Otherwise, check what lies to the left of the equal-sign.
  955.                             if (fwd_infix->symbol == SYM_VAR)
  956.                             {
  957.                                 fwd_infix[1].symbol = SYM_ASSIGN;
  958.                                 continue; // Cascade to the right until the last qualified '=' operator is found.
  959.                             }
  960.                             // Otherwise, it's not a pure/normal variable.  But check if it's an environment var.
  961.                             if (fwd_infix->symbol != SYM_DYNAMIC || !SYM_DYNAMIC_IS_VAR_NORMAL_OR_CLIP(fwd_infix))
  962.                                 break; // It qualifies as neither SYM_DYNAMIC nor SYM_VAR.
  963.                             // Otherwise, this is an environment variable being assigned something, so treat
  964.                             // it as a normal variable rather than an environment variable. This is because
  965.                             // by tradition (and due to the fact that not many people would want it),
  966.                             // direct assignment to environment variables isn't supported by anything other
  967.                             // than EnvSet.
  968.                             fwd_infix->symbol = SYM_VAR; // Convert dynamic to a normal variable, see above.
  969.                             fwd_infix[1].symbol = SYM_ASSIGN;
  970.                             // And now cascade to the right until the last qualified '=' operator is found.
  971.                         }
  972.                     }
  973.                     //else it's a function comma, so don't put it in stack because function commas aren't
  974.                     // needed and they would probably prevent proper evaluation.  Only statement-separator
  975.                     // commas need to go onto the stack (see SYM_COMMA further below for comments).
  976.                 }
  977.                 ++this_infix; // Regardless of the outcome above, move rightward to the next infix item.
  978.             }
  979.             else // Stack item's precedence >= infix's (if equal, left-to-right evaluation order is in effect).
  980.                 goto standard_pop_into_postfix;
  981.         } // switch(infix_symbol)
  982.  
  983.         continue; // Avoid falling into the label below except via explicit jump.  Performance: Doing it this way rather than replacing break with continue everywhere above generates slightly smaller and slightly faster code.
  984. standard_pop_into_postfix: // Use of a goto slightly reduces code size.
  985.         this_postfix = STACK_POP;
  986.         this_postfix->circuit_token = NULL; // Set default. It's only ever overridden after it's in the postfix array.
  987.         ++postfix_count;
  988.     } // End of loop that builds postfix array from the infix array.
  989. end_of_infix_to_postfix:
  990.  
  991.     ///////////////////////////////////////////////////
  992.     // EVALUATE POSTFIX EXPRESSION (constructed above).
  993.     ///////////////////////////////////////////////////
  994.     int i, j, s, actual_param_count, delta;
  995.     SymbolType right_is_number, left_is_number, result_symbol;
  996.     double right_double, left_double;
  997.     __int64 right_int64, left_int64;
  998.     char *right_string, *left_string;
  999.     char *right_contents, *left_contents;
  1000.     size_t right_length, left_length;
  1001.     char left_buf[MAX_FORMATTED_NUMBER_LENGTH + 1];  // BIF_OnMessage and SYM_DYNAMIC rely on this one being large enough to hold MAX_VAR_NAME_LENGTH.
  1002.     char right_buf[MAX_FORMATTED_NUMBER_LENGTH + 1]; // Only needed for holding numbers
  1003.     char *result; // "result" is used for return values and also the final result.
  1004.     VarSizeType result_length;
  1005.     size_t result_size, alloca_usage = 0; // v1.0.45: Track amount of alloca mem to avoid stress on stack from extreme expressions (mostly theoretical).
  1006.     BOOL done, done_and_have_an_output_var, make_result_persistent, left_branch_is_true
  1007.         , left_was_negative, is_pre_op; // BOOL vs. bool benchmarks slightly faster, and is slightly smaller in code size (or maybe it's cp1's int vs. char that shrunk it).
  1008.     ExprTokenType *circuit_token;
  1009.     Var *sym_assign_var, *temp_var;
  1010.     VarBkp *var_backup = NULL;  // If needed, it will hold an array of VarBkp objects. v1.0.40.07: Initialized to NULL to facilitate an approach that's more maintainable.
  1011.     int var_backup_count; // The number of items in the above array (when it's non-NULL).
  1012.  
  1013.     // v1.0.44.06: EXPR_SMALL_MEM_LIMIT is the means by which _alloca() is used to boost performance a
  1014.     // little by avoiding the overhead of malloc+free for small strings.  The limit should be something
  1015.     // small enough that the chance that even 10 of them would cause stack overflow is vanishingly small
  1016.     // (the program is currently compiled to allow stack to expand anyway).  Even in a worst-case
  1017.     // scenario where an expression is composed entirely of functions and they all need to use this
  1018.     // limit of stack space, there's a practical limit on how many functions you can call in an
  1019.     // expression due to MAX_TOKENS (probably around MAX_TOKENS / 3).
  1020.     #define EXPR_SMALL_MEM_LIMIT 4097
  1021.     #define EXPR_ALLOCA_LIMIT 40000  // v1.0.45: Just as an extra precaution against stack stress in extreme/theoretical cases.
  1022.  
  1023.     // For each item in the postfix array: if it's an operand, push it onto stack; if it's an operator or
  1024.     // function call, evaluate it and push its result onto the stack.
  1025.     for (i = 0; i < postfix_count; ++i) // Performance: Using a handle to traverse the postfix array rather than array indexing unexpectedly benchmarked 3% slower (perhaps not statistically significant due to being caused by CPU cache hits or compiler's use of registers).  Because of that, there's not enough reason to switch to that method -- though it does generate smaller code (perhaps a savings of 200 bytes).
  1026.     {
  1027.         ExprTokenType &this_token = *postfix[i];  // For performance and convenience.
  1028.  
  1029.         // At this stage, operands in the postfix array should be SYM_OPERAND, SYM_STRING, or SYM_DYNAMIC.
  1030.         // But all are checked since that operation is just as fast:
  1031.         if (IS_OPERAND(this_token.symbol)) // If it's an operand, just push it onto stack for use by an operator in a future iteration.
  1032.         {
  1033.             if (this_token.symbol == SYM_DYNAMIC) // CONVERTED HERE/EARLY TO SOMETHING *OTHER* THAN SYM_DYNAMIC so that no later stages need any handling for them as operands. SYM_DYNAMIC is quite similar to SYM_FUNC/BIF in this respect.
  1034.             {
  1035.                 if (!SYM_DYNAMIC_IS_DOUBLE_DEREF(this_token)) // It's a built-in variable or potential environment variable.
  1036.                 {
  1037.                     result_size = this_token.var->Get() + 1; // Get() is used even for environment vars because it has a cache that improves their performance.
  1038.                     if (result_size == 1)
  1039.                     {
  1040.                         if (this_token.var->Type() == VAR_NORMAL) // It's an empty variable, so treated as a non-environment (normal) var.
  1041.                         {
  1042.                             // The following is done here rather than during infix creation/tokenizing because
  1043.                             // 1) It's more correct because it's conceivable that some part of the expression
  1044.                             //    that has already been evaluated before this_token has newly made an environment
  1045.                             //    variable blank or non-blank, which should be detected here (i.e. only at the
  1046.                             //    last possible moment).  For example, a function might have the side-effect of
  1047.                             //    altering an environment variable.
  1048.                             // 2) It performs better because Get()'s environment variable cache is most effective
  1049.                             //    when each size-Get() is followed immediately by a contents-Get() for the same
  1050.                             //    variable.
  1051.                             // Must make empty variables that aren't environment variables into SYM_VAR so that
  1052.                             // they can be passed by reference into functions, their address can be taken with
  1053.                             // the '&' operator, and so that they can be the lvalue for an assignment.
  1054.                             // Environment variables aren't supported for any of that because it would be silly
  1055.                             // in most cases, and would probably complicate the code far more than its worth.
  1056.                             this_token.symbol = SYM_VAR; // The fact that a SYM_VAR operand is always VAR_NORMAL (with one limited exception) is relied upon in several places such as built-in functions.
  1057.                         }
  1058.                         else // It's a built-in variable that's blank.
  1059.                         {
  1060.                             this_token.marker = "";
  1061.                             this_token.symbol = SYM_STRING;
  1062.                         }
  1063.                         goto push_this_token;
  1064.                     }
  1065.                     // Otherwise, it's not an empty string.  But there's a slight chance it could be a normal
  1066.                     // variable rather than a built-in or environment variable.  This happens when another
  1067.                     // part of this same expression (such as a UDF via ByRef) has put contents into this
  1068.                     // variable since the time this item was made SYM_DYNAMIC.  In other words, we wouldn't
  1069.                     // have made it SYM_DYNAMIC in the first place if we'd known that was going to happen.
  1070.                     if (this_token.var->Type() == VAR_NORMAL && this_token.var->Length()) // v1.0.46.07: It's not a built-in or environment variable.
  1071.                     {
  1072.                         this_token.symbol = SYM_VAR; // The fact that a SYM_VAR operand is always VAR_NORMAL (with one limited exception) is relied upon in several places such as built-in functions.
  1073.                         goto push_this_token;
  1074.                     }
  1075.                     // Otherwise, it's an environment variable or built-in variable. Need some memory to store it.
  1076.                     // The following section is similar to that in the make_result_persistent section further
  1077.                     // below.  So maintain them together and see it for more comments.
  1078.                     // Must cast to int to avoid loss of negative values:
  1079.                     if (result_size <= (int)(aDerefBufSize - (target - aDerefBuf))) // There is room at the end of our deref buf, so use it.
  1080.                     {
  1081.                         // Point result to its new, more persistent location:
  1082.                         result = target;
  1083.                         target += result_size; // Point it to the location where the next string would be written.
  1084.                     }
  1085.                     else if (result_size < EXPR_SMALL_MEM_LIMIT && alloca_usage < EXPR_ALLOCA_LIMIT) // See comments at EXPR_SMALL_MEM_LIMIT.
  1086.                     {
  1087.                         result = (char *)_alloca(result_size);
  1088.                         alloca_usage += result_size; // This might put alloca_usage over the limit by as much as EXPR_SMALL_MEM_LIMIT, but that is fine because it's more of a guideline than a limit.
  1089.                     }
  1090.                     else // Need to create some new persistent memory for our temporary use.
  1091.                     {
  1092.                         if (mem_count == MAX_EXPR_MEM_ITEMS // No more slots left (should be nearly impossible).
  1093.                             || !(mem[mem_count] = (char *)malloc(result_size)))
  1094.                         {
  1095.                             LineError(ERR_OUTOFMEM ERR_ABORT, FAIL, this_token.var->mName);
  1096.                             goto abort;
  1097.                         }
  1098.                         // Point result to its new, more persistent location:
  1099.                         result = mem[mem_count];
  1100.                         ++mem_count; // Must be done last.
  1101.                     }
  1102.                     this_token.var->Get(result); // MUST USE "result" TO AVOID OVERWRITING MARKER/VAR UNION.
  1103.                     this_token.marker = result;  // Must be done last because marker and var overlap in union.
  1104.                     this_token.symbol = SYM_OPERAND; // Generic operand so that it can later be interpreted as a number (if it's numeric).
  1105.                 }
  1106.                 else // Double-deref such as Array%i%.
  1107.                 {
  1108.                     // Start off by looking for the first deref.
  1109.                     deref = (DerefType *)this_token.var; // MUST BE DONE PRIOR TO OVERWRITING MARKER/UNION BELOW.
  1110.                     cp = this_token.buf; // Start at the begining of this arg's text.
  1111.                     int var_name_length = 0;
  1112.  
  1113.                     this_token.marker = "";         // Set default in case of early goto.  Must be done after above.
  1114.                     this_token.symbol = SYM_STRING; //
  1115.  
  1116.                     // Loadtime validation has ensured that none of these derefs are function-calls
  1117.                     // (i.e. deref->is_function is alway false).  Loadtime logic seems incapable of
  1118.                     // producing function-derefs inside something that would later be interpreted
  1119.                     // as a double-deref.
  1120.                     for (; deref->marker; ++deref)  // A deref with a NULL marker terminates the list. "deref" was initialized higher above.
  1121.                     {
  1122.                         // FOR EACH DEREF IN AN ARG (if we're here, there's at least one):
  1123.                         // Copy the chars that occur prior to deref->marker into the buffer:
  1124.                         for (; cp < deref->marker && var_name_length < MAX_VAR_NAME_LENGTH; left_buf[var_name_length++] = *cp++);
  1125.                         if (var_name_length >= MAX_VAR_NAME_LENGTH && cp < deref->marker) // The variable name would be too long!
  1126.                             goto push_this_token; // For simplicity and in keeping with the tradition that expressions generally don't display runtime errors, just treat it as a blank.
  1127.                         // Now copy the contents of the dereferenced var.  For all cases, aBuf has already
  1128.                         // been verified to be large enough, assuming the value hasn't changed between the
  1129.                         // time we were called and the time the caller calculated the space needed.
  1130.                         if (deref->var->Get() > (VarSizeType)(MAX_VAR_NAME_LENGTH - var_name_length)) // The variable name would be too long!
  1131.                             goto push_this_token; // For simplicity and in keeping with the tradition that expressions generally don't display runtime errors, just treat it as a blank.
  1132.                         var_name_length += deref->var->Get(left_buf + var_name_length);
  1133.                         // Finally, jump over the dereference text. Note that in the case of an expression, there might not
  1134.                         // be any percent signs within the text of the dereference, e.g. x + y, not %x% + %y%.
  1135.                         cp += deref->length;
  1136.                     }
  1137.  
  1138.                     // Copy any chars that occur after the final deref into the buffer:
  1139.                     for (; *cp && var_name_length < MAX_VAR_NAME_LENGTH; left_buf[var_name_length++] = *cp++);
  1140.                     if (var_name_length >= MAX_VAR_NAME_LENGTH && *cp // The variable name would be too long!
  1141.                         || !var_name_length) // It resolves to an empty string (e.g. a simple dynamic var like %Var% where Var is blank).
  1142.                         goto push_this_token; // For simplicity and in keeping with the tradition that expressions generally don't display runtime errors, just treat it as a blank.
  1143.  
  1144.                     // Terminate the buffer, even if nothing was written into it:
  1145.                     left_buf[var_name_length] = '\0';
  1146.  
  1147.                     // In v1.0.31, FindOrAddVar() vs. FindVar() is called below to support the passing of non-existent
  1148.                     // array elements ByRef, e.g. Var:=MyFunc(Array%i%) where the MyFunc function's parameter is
  1149.                     // defined as ByRef, would effectively create the new element Array%i% if it doesn't already exist.
  1150.                     // Since at this stage we don't know whether this particular double deref is to be sent as a param
  1151.                     // to a function, or whether it will be byref, this is done unconditionally for all double derefs
  1152.                     // since it seems relatively harmless to create a blank variable in something like var := Array%i%
  1153.                     // (though it will produce a runtime error if the double resolves to an illegal variable name such
  1154.                     // as one containing spaces).
  1155.                     // The use of ALWAYS_PREFER_LOCAL below improves flexibility of assume-global functions
  1156.                     // by allowing this command to resolve to a local first if such a local exists:
  1157.                     if (   !(temp_var = g_script.FindOrAddVar(left_buf, var_name_length, ALWAYS_PREFER_LOCAL))   )
  1158.                     {
  1159.                         // Above already displayed the error.  As of v1.0.31, this type of error is displayed and
  1160.                         // causes the current thread to terminate, which seems more useful than the old behavior
  1161.                         // that tolerated anything in expressions.
  1162.                         goto abort;
  1163.                     }
  1164.                     // Otherwise, var was found or created.
  1165.                     if (temp_var->Type() != VAR_NORMAL)
  1166.                     {
  1167.                         // Non-normal variables such as Clipboard and A_ScriptFullPath are not allowed to be
  1168.                         // generated from a double-deref such as A_Script%VarContainingFullPath% because:
  1169.                         // Update: The only good reason now is code simplicity.  Reason #1 below could probably
  1170.                         // be solved via SYM_DYNAMIC.
  1171.                         // 1) Anything that needed their contents would have to find memory in which to store
  1172.                         //    the result of Var::Get(), which would complicate the code since such handling would have
  1173.                         //    to be added.
  1174.                         // 2) It doesn't appear to have much use, not even for passing them as a ByRef parameter to
  1175.                         //    a function (since they're read-only [except Clipboard, but temporary memory would be
  1176.                         //    needed somewhere if the clipboard contains files that need to be expanded to text] and
  1177.                         //    essentially global by their very nature), and the value of catching unintended usages
  1178.                         //    seems more important than any flexibilty that might add.
  1179.                         goto push_this_token; // For simplicity and in keeping with the tradition that expressions generally don't display runtime errors, just treat it as a blank.
  1180.                     }
  1181.                     // Otherwise:
  1182.                     // Even if it's an environment variable, it gets added as SYM_VAR.  However, unlike other
  1183.                     // aspects of the program, double-derefs that resolve to environment variables will be seen
  1184.                     // as always-blank due to the use of Var::Contents() vs. Var::Get() in various places.
  1185.                     // This seems okay due to the extreme rarity of anyone intentionally wanting a double
  1186.                     // reference such as Array%i% to resolve to the name of an environment variable.
  1187.                     this_token.symbol = SYM_VAR; // The fact that a SYM_VAR operand is always VAR_NORMAL (with one limited exception) is relied upon in several places such as built-in functions.
  1188.                     this_token.var = temp_var;
  1189.                 } // Double-deref.
  1190.             } // if (this_token.symbol == SYM_DYNAMIC)
  1191.             goto push_this_token;
  1192.         } // if (IS_OPERAND(this_token.symbol))
  1193.  
  1194.         if (this_token.symbol == SYM_FUNC) // A call to a function (either built-in or defined by the script).
  1195.         {
  1196.             Func &func = *this_token.deref->func; // For performance.
  1197.             actual_param_count = this_token.deref->param_count; // For performance.
  1198.             if (actual_param_count > stack_count) // Prevent stack underflow (probably impossible if actual_param_count is accurate).
  1199.                 goto abnormal_end;
  1200.             if (func.mIsBuiltIn)
  1201.             {
  1202.                 // Adjust the stack early to simplify.  Above already confirmed that this won't underflow.
  1203.                 // Pop the actual number of params involved in this function-call off the stack.  Load-time
  1204.                 // validation has ensured that this number is always less than or equal to the number of
  1205.                 // parameters formally defined by the function.  Therefore, there should never be any leftover
  1206.                 // function-params on the stack after this is done:
  1207.                 stack_count -= actual_param_count; // The function called below will see this portion of the stack as an array of its parameters.
  1208.                 this_token.symbol = SYM_INTEGER; // Set default return type so that functions don't have to do it if they return INTs.
  1209.                 this_token.marker = func.mName;  // Inform function of which built-in function called it (allows code sharing/reduction). Can't use circuit_token because it's value is still needed later below.
  1210.                 this_token.buf = left_buf;       // mBIF() can use this to store a string result, and for other purposes.
  1211.  
  1212.                 // BACK UP THE CIRCUIT TOKEN (it's saved because it can be non-NULL at this point (verified
  1213.                 // through code review).
  1214.                 circuit_token = this_token.circuit_token;
  1215.                 this_token.circuit_token = NULL; // Init to detect whether the called function allocates it (i.e. we're overloading it with a new purpose).
  1216.                 // RESIST TEMPTATIONS TO OPTIMIZE CIRCUIT_TOKEN by passing output_var as circuit_token
  1217.                 // when done==true (i.e. the built-in function could then assign directly to output_var).
  1218.                 // It doesn't help performance at all except for a mere 10% or less in certain fairly rare cases.
  1219.                 // More importantly, it hurts maintainability because it makes RegExReplace() more complicated
  1220.                 // than it already is, and worse: each BIF would have to check that output_var doesn't overlap
  1221.                 // with its input/source strings because if it does, the function must not initialize a default
  1222.                 // in output_var before starting (and avoiding this would further complicate the code).
  1223.                 // Here is the crux of the abandoned approach: Any function that wishes to pass memory back to
  1224.                 // us via circuit_token: When circuit_token!=NULL, that function MUST INSTEAD: 1) Turn that
  1225.                 // memory over to output_var via AcceptNewMem(); 2) Set circuit_token to NULL to indicate to
  1226.                 // us that it is a user of circuit_token.
  1227.  
  1228.                 // CALL THE FUNCTION:
  1229.                 func.mBIF(this_token, stack + stack_count, actual_param_count);
  1230.  
  1231.                 // RESTORE THE CIRCUIT TOKEN (after handling what came back inside it):
  1232.                 #define EXPR_IS_DONE (!stack_count && i == postfix_count-1) // True if we've used up the last of the operators & operands.
  1233.                 done = EXPR_IS_DONE;
  1234.                 done_and_have_an_output_var = done && output_var; // i.e. this is ACT_ASSIGNEXPR and we've now produced the final result.
  1235.                 make_result_persistent = true; // Set default.
  1236.                 if (this_token.circuit_token) // The called function allocated some memory here (to facilitate returning long strings) and turned it over to us.
  1237.                 {
  1238.                     // In most cases, the string stored in circuit_token is the same address as this_token.marker
  1239.                     // (i.e. what is named "result" further below), because that's what the built-in functions
  1240.                     // are normally using the memory for.
  1241.                     if ((char *)this_token.circuit_token == this_token.marker) // circuit_token is checked in case caller alloc'd mem but didn't use it as its actual result.
  1242.                     {
  1243.                         // v1.0.45: If possible, take a shortcut for performance.  Doing it this way saves at least
  1244.                         // two memcpy's (one into deref buffer and then another back into the output_var by
  1245.                         // ACT_ASSIGNEXPR itself).  In some cases is also saves from having to expand the deref
  1246.                         // buffer as well as the output_var (since it's current memory might be too small to hold
  1247.                         // the new memory block). Thus we give it a new block directly to avoid all of that.
  1248.                         // This should be a big boost to performance when long strings are involved.
  1249.                         // So now, turn over responsibility for this memory to the variable. The called function
  1250.                         // is responsible for having stored the length of what's in the memory as an overload of
  1251.                         // this_token.buf, but only when that memory is the result (currently might always be true).
  1252.                         if (done_and_have_an_output_var)
  1253.                         {
  1254.                             // AcceptNewMem() will shrink the memory for us, via _expand(), if there's a lot of
  1255.                             // extra/unused space in it.
  1256.                             output_var->AcceptNewMem((char *)this_token.circuit_token, (VarSizeType)(size_t)this_token.buf); // "buf" is the length. See comment higher above.
  1257.                             goto normal_end_skip_output_var; // No need to restore circuit_token because the expression is finished.
  1258.                         }
  1259.                         if (i < postfix_count-1 && postfix[i+1]->symbol == SYM_ASSIGN // Next operation is ":=".
  1260.                             && stack_count && stack[stack_count-1]->symbol == SYM_VAR // i.e. let the next iteration handle it instead of doing it here.  Further below relies on this having been checked.
  1261.                             && stack[stack_count-1]->var->Type() == VAR_NORMAL) // Don't do clipboard here because: 1) AcceptNewMem() doesn't support it; 2) Could probably use Assign() and then make its result be a newly added mem_count item, but the code complexity doesn't seem worth it given the rarity.
  1262.                         {
  1263.                             // This section is an optimization that avoids memory allocation and an extra memcpy()
  1264.                             // whenever this result is going to be assigned to a variable as the very next step.
  1265.                             // See the comment section higher above for examples.
  1266.                             ExprTokenType &left = *STACK_POP; // Above has already confirmed that it's SYM_VAR and VAR_NORMAL.
  1267.                             // AcceptNewMem() will shrink the memory for us, via _expand(), if there's a lot of
  1268.                             // extra/unused space in it.
  1269.                             left.var->AcceptNewMem((char *)this_token.circuit_token, (VarSizeType)(size_t)this_token.buf);
  1270.                             this_token.circuit_token = postfix[++i]->circuit_token; // Must be done AFTER above. this_token.circuit_token should have been NULL prior to this because the final right-side result of an assignment shouldn't be the last item of an AND/OR/IFF's left branch. The assignment itself would be that.
  1271.                             this_token.var = left.var;   // Make the result a variable rather than a normal operand so that its
  1272.                             this_token.symbol = SYM_VAR; // address can be taken, and it can be passed ByRef. e.g. &(x:=1)
  1273.                             goto push_this_token;
  1274.                         }
  1275.                         make_result_persistent = false; // Override the default set higher above.
  1276.                     } // if (this_token.circuit_token == this_token.marker)
  1277.                     // Since above didn't goto, we're not done yet; so handle this memory the normal way: Mark it
  1278.                     // to be freed at the time we return.
  1279.                     if (mem_count == MAX_EXPR_MEM_ITEMS) // No more slots left (should be nearly impossible).
  1280.                     {
  1281.                         LineError(ERR_OUTOFMEM ERR_ABORT, FAIL, func.mName);
  1282.                         goto abort;
  1283.                     }
  1284.                     mem[mem_count++] = (char *)this_token.circuit_token;
  1285.                 }
  1286.                 //else this_token.circuit_token==NULL, so the BIF just called didn't allocate memory to give to us.
  1287.                 this_token.circuit_token = circuit_token; // Restore it to its original value.
  1288.  
  1289.                 // HANDLE THE RESULT (unless it was already handled above due to an optimization):
  1290.                 if (IS_NUMERIC(this_token.symbol)) // No need for make_result_persistent or early Assign(). Any numeric result can be considered final because it's already stored in permanent memory (namely the token itself).
  1291.                     goto push_this_token; // For code simplicity, the optimization for numeric results is done at a later stage.
  1292.                 //else it's a string, which might need to be moved to persistent memory further below.
  1293.                 if (done_and_have_an_output_var) // RELIES ON THE IS_NUMERIC() CHECK above having been done first.
  1294.                 {
  1295.                     // v1.0.45: This mode improves performance by avoiding the need to copy the result into
  1296.                     // more persistent memory, then avoiding the need to copy it into the defer buffer (which
  1297.                     // also avoids the possibility of needing to expand that buffer).
  1298.                     output_var->Assign(this_token.marker); // Marker can be used because symbol will never be SYM_VAR
  1299.                     goto normal_end_skip_output_var;       // in this case. ALSO: Assign() contains an optimization that avoids actually doing the mem-copying if output_var is being assigned to itself (which can happen in cases like RegExMatch()).
  1300.                 }
  1301.                 // Otherwise, there's no output_var or the expression isn't finished yet, so do normal processing.
  1302.                 if (!*this_token.marker) // Various make-persistent sections further below may rely on this check.
  1303.                 {
  1304.                     this_token.marker = ""; // Ensure it's a constant memory area, not a buf that might get overwritten soon.
  1305.                     goto push_this_token; // For code simplicity, the optimization for numeric results is done at a later stage.
  1306.                 }
  1307.                 // Since above didn't goto, "result" is not SYM_INTEGER/FLOAT/VAR, and not "".  Therefore, it's
  1308.                 // either a pointer to static memory (such as a constant string), or more likely the small buf
  1309.                 // we gave to the BIF for storing small strings.  For simplicity assume its the buf, which is
  1310.                 // volatile and must be made persistent if called for below.
  1311.                 result = this_token.marker; // Marker can be used because symbol will never be SYM_VAR in this case.
  1312.                 if (make_result_persistent) // At this stage, this means that the above wasn't able to determine its correct value yet.
  1313.                     make_result_persistent = !done;
  1314.             }
  1315.             else // It's not a built-in function, or it's a built-in that was overridden with a custom function.
  1316.             {
  1317.                 // If there are other instances of this function already running, either via recursion or
  1318.                 // an interrupted quasi-thread, back up the local variables of the instance that lies immediately
  1319.                 // beneath ours (in turn, that instance is responsible for backing up any instance that lies
  1320.                 // beneath it, and so on, since when recursion collapses or threads resume, they always do so
  1321.                 // in the reverse order in which they were created.
  1322.                 //
  1323.                 // I think the backup-and-restore approach to local variables might enhance performance over
  1324.                 // other approaches, perhaps a lot.  This is because most of the time there will be no other
  1325.                 // instances of a given function on the call stack, thus no backup/restore is needed, and thus
  1326.                 // the function's existing local variables can be reused as though they're globals (i.e.
  1327.                 // memory allocation/deallocation overhead is often completely avoided for non-recursive calls
  1328.                 // to a function after the first).
  1329.                 if (func.mInstances > 0) // i.e. treat negatives as zero to help catch any bugs in the way mInstances is maintained.
  1330.                 {
  1331.                     // Backup/restore of function's variables is needed.
  1332.                     // Only when a backup is needed is it possible for this function to be calling itself recursively,
  1333.                     // either directly or indirectly by means of an intermediate function.  As a consequence, it's
  1334.                     // possible for this function to be passing one or more of its own params or locals to itself.
  1335.                     // The following section compensates for that to handle parameters passed by-value, but it
  1336.                     // doesn't correctly handle passing its own locals/params to itself ByRef, which is in the
  1337.                     // help file as a known limitation.  Also, the below doesn't indicate a failure when stack
  1338.                     // underflow would occur because the loop after this one needs to do that (since this
  1339.                     // one will never execute if a backup isn't needed).  Note that this loop that reviews all
  1340.                     // actual parameters is necessary as a separate loop from the one further below because this
  1341.                     // first one's conversion must occur prior to calling BackupFunctionVars().  In addition, there
  1342.                     // might be other interdependencies between formals and actuals if a function is calling itself
  1343.                     // recursively.
  1344.                     for (j = (actual_param_count < func.mParamCount ? actual_param_count : func.mParamCount) - 1
  1345.                         , s = stack_count // Above line starts at the first formal parameter that has an actual.
  1346.                         ; j > -1; --j) // For each formal parameter (reverse order to mirror the nature of the stack).
  1347.                     {
  1348.                         // --s below moves on to the next item in the stack (without popping):  A check higher
  1349.                         // above has already ensured that this won't cause stack underflow:
  1350.                         ExprTokenType &this_stack_token = *stack[--s]; // Traditional, but doesn't measurably reduce code size and it's unlikely to help performance due to actual flow of control in this case.
  1351.                         if (this_stack_token.symbol == SYM_VAR && !func.mParam[j].is_byref)
  1352.                         {
  1353.                             // Since this formal parameter is passed by value, if it's SYM_VAR, convert it to
  1354.                             // SYM_OPERAND to allow the variables to be backed up and reset further below without
  1355.                             // corrupting any SYM_VARs that happen to be locals or params of this very same
  1356.                             // function.
  1357.                             // DllCall() relies on the fact that this transformation is only done for user
  1358.                             // functions, not built-in ones such as DllCall().  This is because DllCall()
  1359.                             // sometimes needs the variable of a parameter for use as an output parameter.
  1360.                             this_stack_token.marker = this_stack_token.var->Contents();
  1361.                             this_stack_token.symbol = SYM_OPERAND;
  1362.                         }
  1363.                     }
  1364.                     // BackupFunctionVars() will also clear each local variable and formal parameter so that
  1365.                     // if that parameter or local var or is assigned a value by any other means during our call
  1366.                     // to it, new memory will be allocated to hold that value rather than overwriting the
  1367.                     // underlying recursed/interrupted instance's memory, which it will need intact when it's resumed.
  1368.                     if (!Var::BackupFunctionVars(func, var_backup, var_backup_count)) // Out of memory.
  1369.                     {
  1370.                         LineError(ERR_OUTOFMEM ERR_ABORT, FAIL, func.mName);
  1371.                         goto abort;
  1372.                     }
  1373.                 }
  1374.                 //else backup is not needed because there are no other instances of this function on the call-stack.
  1375.                 // So by definition, this function is not calling itself directly or indirectly, therefore there's no
  1376.                 // need to do the conversion of SYM_VAR because those SYM_VARs can't be ones that were blanked out
  1377.                 // due to a function exiting.  In other words, it seems impossible for a there to be no other
  1378.                 // instances of this function on the call-stack and yet SYM_VAR to be one of this function's own
  1379.                 // locals or formal params because it would have no legitimate origin.
  1380.  
  1381.                 j = func.mParamCount - 1; // The index of the last formal parameter. Relied upon by BOTH loops below.
  1382.                 // The following loop will have zero iterations unless at least one formal parameter lacks an actual,
  1383.                 // which should be possible only if the parameter is optional (i.e. has a default value).
  1384.                 for (; j >= actual_param_count; --j) // For each formal parameter that lacks an actual (reverse order to mirror the nature of the stack).
  1385.                 {
  1386.                     // The following worsens performance by 7% under UPX 2.0 but is the faster method on UPX 3.0.
  1387.                     // This could merely be due to unpredictable cache hits/misses in a my particular CPU.
  1388.                     // In addition to being fastest, it also reduces code size by 16 bytes:
  1389.                     FuncParam &this_formal_param = func.mParam[j]; // For performance and convenience.
  1390.                     if (this_formal_param.is_byref) // v1.0.46.13: Allow ByRef parameters to by optional by converting an omitted-actual into a non-alias formal/local.
  1391.                         this_formal_param.var->ConvertToNonAliasIfNecessary(); // Convert from alias-to-normal, if necessary.
  1392.                     switch(this_formal_param.default_type)
  1393.                     {
  1394.                     case PARAM_DEFAULT_STR:   this_formal_param.var->Assign(this_formal_param.default_str);    break;
  1395.                     case PARAM_DEFAULT_INT:   this_formal_param.var->Assign(this_formal_param.default_int64);  break;
  1396.                     case PARAM_DEFAULT_FLOAT: this_formal_param.var->Assign(this_formal_param.default_double); break;
  1397.                     //case PARAM_DEFAULT_NONE: Not possible due to the nature of this loop and due to load-time validation.
  1398.                     }
  1399.                 }
  1400.                 // Pop the actual number of params involved in this function-call off the stack.  Load-time
  1401.                 // validation has ensured that this number is always less than or equal to the number of
  1402.                 // parameters formally defined by the function.  Therefore, there should never be any leftover
  1403.                 // params on the stack after this is done.  Relies upon the value of j established above:
  1404.                 for (; j > -1; --j) // For each formal parameter that has a matching actual (reverse order to mirror the nature of the stack).
  1405.                 {
  1406.                     ExprTokenType &token = *STACK_POP; // A check higher above has already ensured that this won't cause stack underflow.
  1407.                     // Below uses IS_OPERAND rather than checking for only SYM_OPERAND because the stack can contain
  1408.                     // both generic and specific operands.  Specific operands were evaluated by a previous iteration
  1409.                     // of this section.  Generic ones were pushed as-is onto the stack by a previous iteration.
  1410.                     if (!IS_OPERAND(token.symbol)) // Haven't found a way to produce this situation yet, but safe to assume it's possible.
  1411.                     {
  1412.                         Var::FreeAndRestoreFunctionVars(func, var_backup, var_backup_count);
  1413.                         goto abort;
  1414.                     }
  1415.                     // Seems to worsen performance in this case:
  1416.                     //FuncParam &this_formal_param = func.mParam[j]; // For performance and convenience.
  1417.                     if (func.mParam[j].is_byref)
  1418.                     {
  1419.                         // Note that the previous loop might not have checked things like the following because that
  1420.                         // loop never ran unless a backup was needed:
  1421.                         if (token.symbol != SYM_VAR)
  1422.                         {
  1423.                             // In most cases this condition would have been caught by load-time validation.
  1424.                             // However, in the case of badly constructed double derefs, that won't be true
  1425.                             // (though currently, only a double deref that resolves to a built-in variable
  1426.                             // would be able to get this far to trigger this error, because something like
  1427.                             // func(Array%VarContainingSpaces%) would have been caught at an earlier stage above.
  1428.                             LineError(ERR_BYREF ERR_ABORT, FAIL, func.mParam[j].var->mName);
  1429.                             Var::FreeAndRestoreFunctionVars(func, var_backup, var_backup_count);
  1430.                             goto abort;
  1431.                         }
  1432.                         func.mParam[j].var->UpdateAlias(token.var); // Make the formal parameter point directly to the actual parameter's contents.
  1433.                     }
  1434.                     else // This parameter is passed "by value".
  1435.                         // Assign actual parameter's value to the formal parameter (which is itself a
  1436.                         // local variable in the function).  
  1437.                         // If token.var's Type() is always VAR_NORMAL (e.g. never the clipboard).
  1438.                         // A SYM_VAR token can still happen because the previous loop's conversion of all
  1439.                         // by-value SYM_VAR operands into SYM_OPERAND would not have happened if no
  1440.                         // backup was needed for this function.
  1441.                         func.mParam[j].var->Assign(token);
  1442.                 } // for()
  1443.  
  1444.                 aResult = func.Call(result); // Call the UDF.
  1445.                 if (aResult == EARLY_EXIT || aResult == FAIL) // "Early return". See comment below.
  1446.                 {
  1447.                     // Take a shortcut because for backward compatibility, ACT_ASSIGNEXPR (and anything else
  1448.                     // for that matter) is being aborted by this type of early return (i.e. if there's an
  1449.                     // output_var, its contents are left as-is).  In other words, this expression will have
  1450.                     // no result storable by the outside world.
  1451.                     Var::FreeAndRestoreFunctionVars(func, var_backup, var_backup_count);
  1452.                     result_to_return = NULL; // Use NULL to inform our caller that this thread is finished (whether through normal means such as Exit or a critical error).
  1453.                     // Above: The callers of this function know that the value of aResult (which already contains
  1454.                     // the reason for early exit) should be considered valid/meaningful only if result_to_return
  1455.                     // is NULL.  aResult has already been set higher above for our caller.
  1456.                     goto normal_end_skip_output_var; // output_var is left unchanged in these cases.
  1457.                 }
  1458.                 // Since above didn't goto, this isn't an early return, so proceed normally.
  1459.                 if (done = EXPR_IS_DONE) // Resolve macro only once for use in more than one place below.
  1460.                 {
  1461.                     if (output_var // i.e. this is ACT_ASSIGNEXPR and we've now produced the final result.
  1462.                         && !(var_backup && g.CurrentFunc == &func && output_var->IsNonStaticLocal())) // Ordered for short-circuit performance.
  1463.                         // Above line is a fix for v1.0.45.03: It detects whether output_var is among the variables
  1464.                         // that are about to be restored from backup.  If it is, we can't assign to it now
  1465.                         // because it's currently a local that belongs to the instance we're in the middle of
  1466.                         // calling; i.e. it doesn't belong to our instance (which is beneath it on the call stack
  1467.                         // until after the restore-from-backup is done later below).  And we can't assign "result"
  1468.                         // to it *after* the restore because by then result may have been freed (if it happens to be
  1469.                         // a local variable too).  Therefore, continue on to the normal method, which will check
  1470.                         // whether "result" needs to be stored in more persistent memory.
  1471.                     {
  1472.                         // v1.0.45: Take a shortcut for performance.  Doing it this way saves up to two memcpy's
  1473.                         // (make_result_persistent then copy into deref buffer).  In some cases, it also saves
  1474.                         // from having to make_result_persistent and prevents the need to expand the deref buffer.
  1475.                         // HOWEVER, the optimization described next isn't done because not only does it complicate
  1476.                         // the code a lot (such as verifying that the variable isn't static, isn't ALLOC_SIMPLE,
  1477.                         // isn't a ByRef to a global or some other function's local, etc.), there's also currently
  1478.                         // no way to find out which function owns a particular local variable (a name lookup
  1479.                         // via binary search is a possibility, but its performance probably isn't worth it)
  1480.                         // Abandoned idea: When a user-defined function returns one of its local variables,
  1481.                         // the contents of that local variable can be salvaged if it's about to be destroyed
  1482.                         // anyway in conjunction with normal function-call cleanup. In other words, we can take
  1483.                         // that local variable's memory and directly hang it onto the output_var.
  1484.                         result_length = (VarSizeType)strlen(result);
  1485.                         // 1.0.46.06: If the UDF has stored its result in its deref buffer, take possession
  1486.                         // of that buffer, which saves a memcpy of a potentially huge string.  The cost
  1487.                         // of this is that if there are any other UDF-calls pending after this one, the
  1488.                         // code in their bodies will have to create another deref buffer if they need one.
  1489.                         if (result == sDerefBuf && result_length >= MAX_ALLOC_SIMPLE) // Result is in their buffer and it's longer than what can fit in a SimpleHeap variable (avoids wasting SimpleHeap memory).
  1490.                         {
  1491.                             // AcceptNewMem() will shrink the memory for us, via _expand(), if there's a lot of
  1492.                             // extra/unused space in it.
  1493.                             output_var->AcceptNewMem(result, result_length);
  1494.                             NULLIFY_S_DEREF_BUF // Force any UDFs called subsequently by us to create a new deref buffer because this one was just taken over by a variable.
  1495.                         }
  1496.                         else
  1497.                             output_var->Assign(result, result_length);
  1498.                         Var::FreeAndRestoreFunctionVars(func, var_backup, var_backup_count); // Do end-of-function-call cleanup (see comment above). No need to do make_result_persistent section.
  1499.                         goto normal_end_skip_output_var; // Nothing more to do because it has even taken care of output_var already.
  1500.                     }
  1501.                     if (mActionType == ACT_EXPRESSION) // Isolated expression: Outermost function call's result will be ignored, so no need to store it.
  1502.                     {
  1503.                         Var::FreeAndRestoreFunctionVars(func, var_backup, var_backup_count); // Do end-of-function-call cleanup (see comment above). No need to do make_result_persistent section.
  1504.                         goto normal_end_skip_output_var; // No output_var is possible for ACT_EXPRESSION.
  1505.                     }
  1506.                 } // if (done)
  1507.                 // Otherwise (since above didn't goto), the following statement is true:
  1508.                 //    !output_var || !EXPR_IS_DONE || var_backup
  1509.                 // ...so do normal handling of "result". Also, no more optimizations of output_var should be
  1510.                 // attempted because either we're not "done" (i.e. it isn't valid to assign to output_var yet)
  1511.                 // or it isn't safe to store in output_var yet for the reason mentioned earlier.
  1512.                 if (!*result) // RELIED UPON by the make-persistent check further below.
  1513.                 {
  1514.                     // Empty strings are returned pretty often by UDFs, such as when they don't use "return"
  1515.                     // at all.  Therefore, handle them fully now, which should improve performance (since it
  1516.                     // avoids all the other checking later on).  It also doesn't hurt code size because this
  1517.                     // check avoids having to check for empty string in other sections later on.
  1518.                     this_token.marker = ""; // Ensure it's a non-volatile address instead (read-only mem is okay for expression results).
  1519.                     this_token.symbol = SYM_OPERAND; // SYM_OPERAND vs. SYM_STRING probably doesn't matter in the case of empty string, but it's used for consistency with what the other UDF handling further below does.
  1520.                     Var::FreeAndRestoreFunctionVars(func, var_backup, var_backup_count);
  1521.                     goto push_this_token;
  1522.                 }
  1523.                 // The following section is done only for UDFs (i.e. here) rather than for BIFs too because
  1524.                 // the only BIFs remaining that haven't yet been fully handled by earlier optimizations are
  1525.                 // those whose results are almost always tiny (small strings, since floats/integers were already
  1526.                 // handled earlier). So performing the following optimization for them would probably reduce
  1527.                 // average-case performance (since both performing and checking for the optimization is costly).
  1528.                 // It's fairly rare that the following optimization is even be applicable because it requires
  1529.                 // an assignment *internal* to an expression, such as "if not var:=func()", or "a:=b, c:=func()".
  1530.                 // But it seems best to optimize these cases so that commas aren't penalized.
  1531.                 if (i < postfix_count-1 && postfix[i+1]->symbol == SYM_ASSIGN  // Next operation is ":=".
  1532.                     && stack_count && stack[stack_count-1]->symbol == SYM_VAR) // i.e. let the next iteration handle it instead of doing it here.  Further below relies on this having been checked.
  1533.                 {
  1534.                     // This section is an optimization that avoids memory allocation and an extra memcpy()
  1535.                     // whenever this result is going to be assigned to a variable as the very next step.
  1536.                     // See the comment section higher above for examples.
  1537.                     Var &output_var_internal = *stack[stack_count-1]->var; // Above has already confirmed that it's SYM_VAR and VAR_NORMAL.
  1538.                     if (output_var_internal.Type() == VAR_NORMAL // Don't do clipboard here because don't want its result to be SYM_VAR, yet there's no place to store that result (i.e. need to continue on to make-persistent further below to get some memory for it).
  1539.                         && !(var_backup && g.CurrentFunc == &func && output_var_internal.IsNonStaticLocal())) // Ordered for short-circuit performance.
  1540.                         // v1.0.46.09: The above line is a fix for a bug caused by 1.0.46.06's optimization below.
  1541.                         // For details, see comments in a similar line higher above.
  1542.                     {
  1543.                         --stack_count; // This officially pops the lvalue off the stack (now that we know we will be handling this operation here).
  1544.                         // The following section is similar to one higher above, so maintain them together.
  1545.                         result_length = (VarSizeType)strlen(result);
  1546.                         // 1.0.46.06: If the UDF has stored its result in its deref buffer, take possession
  1547.                         // of that buffer, which saves a memcpy of a potentially huge string.  The cost
  1548.                         // of this is that if there are any other UDF-calls pending after this one, the
  1549.                         // code in their bodies will have to create another deref buffer if they need one.
  1550.                         if (result == sDerefBuf && result_length >= MAX_ALLOC_SIMPLE) // Result is in their buffer and it's longer than what can fit in a SimpleHeap variable (avoids wasting SimpleHeap memory).
  1551.                         {
  1552.                             // AcceptNewMem() will shrink the memory for us, via _expand(), if there's a lot of
  1553.                             // extra/unused space in it.
  1554.                             output_var_internal.AcceptNewMem(result, result_length);
  1555.                             NULLIFY_S_DEREF_BUF // Force any UDFs called subsequently by us to get a new deref buffer because this one was just hung onto a variable.
  1556.                         }
  1557.                         else
  1558.                             output_var_internal.Assign(result, result_length);
  1559.                         this_token.circuit_token = postfix[++i]->circuit_token; // this_token.circuit_token should have been NULL prior to this because the final right-side result of an assignment shouldn't be the last item of an AND/OR/IFF's left branch. The assignment itself would be that.
  1560.                         this_token.var = &output_var_internal;   // Make the result a variable rather than a normal operand so that its
  1561.                         this_token.symbol = SYM_VAR; // address can be taken, and it can be passed ByRef. e.g. &(x:=1)
  1562.                         Var::FreeAndRestoreFunctionVars(func, var_backup, var_backup_count); // Do end-of-function-call cleanup (see comment above). No need to do make_result_persistent section.
  1563.                         goto push_this_token;
  1564.                     }
  1565.                 }
  1566.                 // Since above didn't goto:
  1567.                 // The result just returned may need to be copied to a more persistent location.  This is done right
  1568.                 // away if the result is the contents of a local variable (since all locals are about to be freed
  1569.                 // and overwritten), which is assumed to be the case if it's not in the new deref buf because it's
  1570.                 // difficult to distinguish between when the function returned one of its own local variables
  1571.                 // rather than a global or a string/numeric literal).  The only exceptions are covered below.
  1572.                 // Old method, not necessary to be so thorough because "return" always puts its result as the
  1573.                 // very first item in its deref buf.  So this is commneted out in favor of the line below it:
  1574.                 //if (result < sDerefBuf || result >= sDerefBuf + sDerefBufSize)
  1575.                 if (result != sDerefBuf) // Not in their deref buffer (yields correct result even if sDerefBuf is NULL; also, see above.)
  1576.                     // In this case, the result must be assumed to be one of their local variables (since there's
  1577.                     // no way to distinguish between that and a literal string such as "abc"?). So it should be
  1578.                     // immediately copied since if it's a local, it's about to be freed.
  1579.                     make_result_persistent = true;
  1580.                 else // The result must be in their deref buffer, perhaps due to something like "return x+3" or "return bif()" on their part.
  1581.                 {
  1582.                     make_result_persistent = false; // Set default to be possibly overridden below.
  1583.                     if (!done) // There are more operators/operands to be evaluated, but if there are no more function calls, we don't have to make it persistent since their deref buf won't be overwritten by anything during the time we need it.
  1584.                     {
  1585.                         // Since there's more in the stack or postfix array to be evaluated, and since the return
  1586.                         // value is in the new deref buffer, must copy result to somewhere non-volatile whenever
  1587.                         // there's another function-call pending by us.  Note that an empty-string result was
  1588.                         // already checked and fully handled higher above.
  1589.                         // If we don't have have any more user-defined function calls pending, we can skip the
  1590.                         // make-persistent section since this deref buffer will not be overwritten during the
  1591.                         // period we need it.
  1592.                         for (j = i + 1; j < postfix_count; ++j)
  1593.                             if (postfix[j]->symbol == SYM_FUNC)
  1594.                             {
  1595.                                 make_result_persistent = true;
  1596.                                 break;
  1597.                             }
  1598.                     }
  1599.                     //else done==true, so don't have to make it persistent here because the final stage will
  1600.                     // copy it from their deref buf into ours (since theirs is only deleted later, by our caller).
  1601.                     // In this case, leave make_result_persistent set to false.
  1602.                 } // This is the end of the section that determines the value of "make_result_persistent" for UDFs.
  1603.             } // Call to a user-defined function (UDF).
  1604.  
  1605.             this_token.symbol = SYM_OPERAND; // Set default. Use generic, not string, so that any operator of function call that uses this result is free to reinterpret it as an integer or float.
  1606.             if (make_result_persistent) // Both UDFs and built-in functions have ensured make_result_persistent is set.
  1607.             {
  1608.                 // BELOW RELIES ON THE ABOVE ALWAYS HAVING VERFIED FULLY HANDLED RESULT BEING AN EMPTY STRING.
  1609.                 // So now we know result isn't an empty string, which in turn ensures that size > 1 and length > 0,
  1610.                 // which might be relied upon by things further below.
  1611.                 result_size = strlen(result) + 1; // No easy way to avoid strlen currently. Maybe some future revisions to architecture will provide a length.
  1612.                 // Must cast to int to avoid loss of negative values:
  1613.                 if (result_size <= (int)(aDerefBufSize - (target - aDerefBuf))) // There is room at the end of our deref buf, so use it.
  1614.                 {
  1615.                     // Make the token's result the new, more persistent location:
  1616.                     this_token.marker = (char *)memcpy(target, result, result_size); // Benches slightly faster than strcpy().
  1617.                     target += result_size; // Point it to the location where the next string would be written.
  1618.                 }
  1619.                 else if (result_size < EXPR_SMALL_MEM_LIMIT && alloca_usage < EXPR_ALLOCA_LIMIT) // See comments at EXPR_SMALL_MEM_LIMIT.
  1620.                 {
  1621.                     this_token.marker = (char *)memcpy(_alloca(result_size), result, result_size); // Benches slightly faster than strcpy().
  1622.                     alloca_usage += result_size; // This might put alloca_usage over the limit by as much as EXPR_SMALL_MEM_LIMIT, but that is fine because it's more of a guideline than a limit.
  1623.                 }
  1624.                 else // Need to create some new persistent memory for our temporary use.
  1625.                 {
  1626.                     // In real-world scripts the need for additonal memory allocation should be quite
  1627.                     // rare because it requires a combination of worst-case situations:
  1628.                     // - Called-function's return value is in their new deref buf (rare because return
  1629.                     //   values are more often literal numbers, true/false, or variables).
  1630.                     // - We still have more functions to call here (which is somewhat atypical).
  1631.                     // - There's insufficient room at the end of the deref buf to store the return value
  1632.                     //   (unusual because the deref buf expands in block-increments, and also because
  1633.                     //   return values are usually small, such as numbers).
  1634.                     if (mem_count == MAX_EXPR_MEM_ITEMS // No more slots left (should be nearly impossible).
  1635.                         || !(mem[mem_count] = (char *)malloc(result_size)))
  1636.                     {
  1637.                         LineError(ERR_OUTOFMEM ERR_ABORT, FAIL, func.mName);
  1638.                         goto abort;
  1639.                     }
  1640.                     // Make the token's result the new, more persistent location:
  1641.                     this_token.marker = (char *)memcpy(mem[mem_count], result, result_size); // Benches slightly faster than strcpy().
  1642.                     ++mem_count; // Must be done last.
  1643.                 }
  1644.             }
  1645.             else // make_result_persistent==false
  1646.                 this_token.marker = result;
  1647.  
  1648.             if (!func.mIsBuiltIn)
  1649.             {
  1650.                 // Free the memory of all the just-completed function's local variables.  This is done in
  1651.                 // both of the following cases:
  1652.                 // 1) There are other instances of this function beneath us on the call-stack: Must free
  1653.                 //    the memory to prevent a memory leak for any variable that existed prior to the call
  1654.                 //    we just did.  Although any local variables newly created as a result of our call
  1655.                 //    technically don't need to be freed, they are freed for simplicity of code and also
  1656.                 //    because not doing so might result in side-effects for instances of this function that
  1657.                 //    lie beneath ours that would expect such nonexistent variables to have blank contents
  1658.                 //    when *they* create it.
  1659.                 // 2) No other instances of this function exist on the call stack: The memory is freed and
  1660.                 //    the contents made blank for these reasons:
  1661.                 //    a) Prevents locals from all being static in duration, and users coming to rely on that,
  1662.                 //       since in the future local variables might be implemented using a non-persistent method
  1663.                 //       such as hashing (rather than maintaining a permanent list of Var*'s for each function).
  1664.                 //    b) To conserve memory between calls (in case the function's locals use a lot of memory).
  1665.                 //    c) To yield results consistent with when the same function is called while other instances
  1666.                 //       of itself exist on the call stack.  In other words, it would be inconsistent to make
  1667.                 //       all variables blank for case #1 above but not do it here in case #2.
  1668.                 Var::FreeAndRestoreFunctionVars(func, var_backup, var_backup_count);
  1669.             } // if (!func.mIsBuiltIn)
  1670.             goto push_this_token;
  1671.         } // if (this_token.symbol == SYM_FUNC)
  1672.  
  1673.         if (this_token.symbol == SYM_IFF_ELSE) // This is encountered when a ternary's condition was found to be false by a prior iteration.
  1674.         {
  1675.             if (this_token.circuit_token // This ternary's result is some other ternary's condition (somewhat rare, so the simple method used here isn't much a concern for performance optimization).
  1676.                 && stack_count) // Prevent underflow (this check might not be necessary; so it's just in case there's a way it can happen).
  1677.             {
  1678.                 // To support *cascading* short-circuit when ternary/IFF's are nested inside each other, pop the
  1679.                 // topmost operand off the stack to modify its circuit_token.  The routine below will then
  1680.                 // use this as the parent IFF's *condition*, which is an non-operand of sorts because it's
  1681.                 // used only to determine which branch of an IFF will become the operand/result of this IFF.
  1682.                 circuit_token = this_token.circuit_token; // Temp copy to avoid overwrite by the next line.
  1683.                 this_token = *STACK_POP; // Struct copy.  Doing it this way is more maintainable than other methods, and is unlikely to perform much worse.
  1684.                 this_token.circuit_token = circuit_token;
  1685.                 goto non_null_circuit_token; // Must do this so that it properly evaluates this_token as the next ternary's condition.
  1686.             }
  1687.             // Otherwise, ignore it because its final result has already been evaluated and pushed onto the
  1688.             // stack via prior iterations.  In other words, this ELSE branch was the IFF's final result, which
  1689.             // is now topmost on the stack for use as an operand by a future operator.
  1690.             continue;
  1691.         }
  1692.  
  1693.         // Since the above didn't "goto" or continue, this token must be a unary or binary operator.
  1694.         // Get the first operand for this operator (for non-unary operators, this is the right-side operand):
  1695.         if (!stack_count) // Prevent stack underflow.  An expression such as -*3 causes this.
  1696.             goto abnormal_end;
  1697.         ExprTokenType &right = *STACK_POP;
  1698.         // Below uses IS_OPERAND rather than checking for only SYM_OPERAND because the stack can contain
  1699.         // both generic and specific operands.  Specific operands were evaluated by a previous iteration
  1700.         // of this section.  Generic ones were pushed as-is onto the stack by a previous iteration.
  1701.         if (!IS_OPERAND(right.symbol)) // Haven't found a way to produce this situation yet, but safe to assume it's possible.
  1702.             goto abnormal_end;
  1703.  
  1704.         // The following check is done after popping "right" off the stack because a prior iteration has set up
  1705.         // SYM_IFF_THEN to be a unary operator of sorts.
  1706.         if (this_token.symbol == SYM_IFF_THEN) // This is encountered when a ternary's condition was found to be true by a prior iteration.
  1707.         {
  1708.             if (!this_token.circuit_token) // This check is needed for syntax errors such as "1 ? 2" (no matching else) and perhaps other unusual circumstances.
  1709.                 goto abnormal_end; // Seems best to consider it a syntax error rather than supporting partial functionality (hard to imagine much legitimate need to omit an ELSE).
  1710.             // SYM_IFF_THEN is encountered only when a previous iteration has determined that the ternary's condition
  1711.             // is true.  At this stage, the ternary's "THEN" branch has already been evaluated and stored in
  1712.             // "right".  So skip over its "else" branch (short-circuit) because that doesn't need to be evaluated.
  1713.             for (++i; postfix[i] != this_token.circuit_token; ++i); // Should always be found, so no need to check postfix_count.
  1714.             // And very soon, the outer loop's ++i will skip over the SYM_IFF_ELSE just found above.
  1715.             right.circuit_token = this_token.circuit_token->circuit_token; // Can be NULL (in fact, it usually is).
  1716.             this_token = right;   // Struct copy to set things up for push_this_token, which in turn is needed
  1717.             goto push_this_token; // (rather than a simple STACK_PUSH(right)) because it checks for *cascading* short circuit in cases where this ternary's result is the boolean condition of another ternary.
  1718.         }
  1719.  
  1720.         if (this_token.symbol == SYM_COMMA) // This can only be a statement-separator comma, not a function comma, since function commas weren't put into the postfix array.
  1721.             // Do nothing other than discarding the right-side operand that was just popped off the stack.
  1722.             // This collapses the two sub-statements delimated by a given comma into a single result for
  1723.             // subequent uses by another operator.  Unlike C++, the leftmost operand is preserved, not the
  1724.             // rightmost.  This is because it's faster to just discard the topmost item on the stack, but
  1725.             // more importantly it allows ACT_ASSIGNEXPR, ACT_ADD, and others to work properly.  For example:
  1726.             //    Var:=5, Var1:=(Var2:=1, Var3:=2)
  1727.             // Without the behavior implemented here, the above would wrongly put Var3's rvalue into Var2.
  1728.             continue;
  1729.  
  1730.         if (this_token.symbol != SYM_ASSIGN) // SYM_ASSIGN doesn't need "right" to be resolved.
  1731.         {
  1732.             // If the operand is still generic/undetermined, find out whether it is a string, integer, or float:
  1733.             switch(right.symbol)
  1734.             {
  1735.             case SYM_VAR:
  1736.                 right_contents = right.var->Contents(); // Can be the clipboard in this case, but it works even then.
  1737.                 right_is_number = IsPureNumeric(right_contents, true, false, true);
  1738.                 break;
  1739.             case SYM_OPERAND:
  1740.                 right_contents = right.marker;
  1741.                 right_is_number = IsPureNumeric(right_contents, true, false, true);
  1742.                 break;
  1743.             case SYM_STRING:
  1744.                 right_contents = right.marker;
  1745.                 right_is_number = PURE_NOT_NUMERIC; // Explicitly-marked strings are not numeric, which allows numeric strings to be compared as strings rather than as numbers.
  1746.             default: // INTEGER or FLOAT
  1747.                 // right_contents is left uninitialized for performance and to catch bugs.
  1748.                 right_is_number = right.symbol;
  1749.             }
  1750.         }
  1751.  
  1752.         // IF THIS IS A UNARY OPERATOR, we now have the single operand needed to perform the operation.
  1753.         // The cases in the switch() below are all unary operators.  The other operators are handled
  1754.         // in the switch()'s default section:
  1755.         sym_assign_var = NULL; // Set default for use at the bottom of the following switch().
  1756.         switch (this_token.symbol)
  1757.         {
  1758.         case SYM_AND: // These are now unary operators because short-circuit has made them so.  If the AND/OR
  1759.         case SYM_OR:  // had short-circuited, we would never be here, so this is the right branch of a non-short-circuit AND/OR.
  1760.             if (right_is_number == PURE_INTEGER)
  1761.                 this_token.value_int64 = (right.symbol == SYM_INTEGER ? right.value_int64 : ATOI64(right_contents)) != 0;
  1762.             else if (right_is_number == PURE_FLOAT)
  1763.                 this_token.value_int64 = (right.symbol == SYM_FLOAT ? right.value_double : atof(right_contents)) != 0.0;
  1764.             else // This is either a non-numeric string or a numeric raw literal string such as "123".
  1765.                 // All non-numeric strings are considered TRUE here.  In addition, any raw literal string,
  1766.                 // even "0", is considered to be TRUE.  This relies on the fact that right.symbol will be
  1767.                 // SYM_OPERAND/generic (and thus handled higher above) for all pure-numeric strings except
  1768.                 // explicit raw literal strings.  Thus, if something like !"0" ever appears in an expression,
  1769.                 // it evaluates to !true.  EXCEPTION: Because "if x" evaluates to false when X is blank,
  1770.                 // it seems best to have "if !x" evaluate to TRUE.
  1771.                 this_token.value_int64 = *right_contents != '\0';
  1772.             this_token.symbol = SYM_INTEGER; // Result of AND or OR is always a boolean integer (one or zero).
  1773.             break;
  1774.  
  1775.         case SYM_NEGATIVE:  // Unary-minus.
  1776.             if (right_is_number == PURE_INTEGER)
  1777.                 this_token.value_int64 = -(right.symbol == SYM_INTEGER ? right.value_int64 : ATOI64(right_contents));
  1778.             else if (right_is_number == PURE_FLOAT)
  1779.                 // Overwrite this_token's union with a float. No need to have the overhead of ATOF() since PURE_FLOAT is never hex.
  1780.                 this_token.value_double = -(right.symbol == SYM_FLOAT ? right.value_double : atof(right_contents));
  1781.             else // String.
  1782.             {
  1783.                 // Seems best to consider the application of unary minus to a string, even a quoted string
  1784.                 // literal such as "15", to be a failure.  UPDATE: For v1.0.25.06, invalid operations like
  1785.                 // this instead treat the operand as an empty string.  This avoids aborting a long, complex
  1786.                 // expression entirely just because on of its operands is invalid.  However, the net effect
  1787.                 // in most cases might be the same, since the empty string is a non-numeric result and thus
  1788.                 // will cause any operator it is involved with to treat its other operand as a string too.
  1789.                 // And the result of a math operation on two strings is typically an empty string.
  1790.                 this_token.marker = "";
  1791.                 this_token.symbol = SYM_STRING;
  1792.                 break;
  1793.             }
  1794.             // Since above didn't "break":
  1795.             this_token.symbol = right_is_number; // Convert generic SYM_OPERAND into a specific type: float or int.
  1796.             break;
  1797.  
  1798.         // Both nots are equivalent at this stage because precedence was already acted upon by infix-to-postfix:
  1799.         case SYM_LOWNOT:  // The operator-word "not".
  1800.         case SYM_HIGHNOT: // The symbol !
  1801.             if (right_is_number == PURE_INTEGER)
  1802.                 this_token.value_int64 = !(right.symbol == SYM_INTEGER ? right.value_int64 : ATOI64(right_contents));
  1803.             else if (right_is_number == PURE_FLOAT) // Convert to float, not int, so that a number between 0.0001 and 0.9999 is considered "true".
  1804.                 // Using ! vs. comparing explicitly to 0.0 might generate faster code, and K&R implies it's okay:
  1805.                 this_token.value_int64 = !(right.symbol == SYM_FLOAT ? right.value_double : atof(right_contents));
  1806.             else // This is either a non-numeric string or a numeric raw literal string such as "123".
  1807.                 // All non-numeric strings are considered TRUE here.  In addition, any raw literal string,
  1808.                 // even "0", is considered to be TRUE.  This relies on the fact that right.symbol will be
  1809.                 // SYM_OPERAND/generic (and thus handled higher above) for all pure-numeric strings except
  1810.                 // explicit raw literal strings.  Thus, if something like !"0" ever appears in an expression,
  1811.                 // it evaluates to !true.  EXCEPTION: Because "if x" evaluates to false when X is blank,
  1812.                 // it seems best to have "if !x" evaluate to TRUE.
  1813.                 this_token.value_int64 = !*right_contents; // i.e. result is false except for empty string because !"string" is false.
  1814.             this_token.symbol = SYM_INTEGER; // Result of above is always a boolean integer (one or zero).
  1815.             break;
  1816.  
  1817.         case SYM_POST_INCREMENT: // These were added in v1.0.46.  It doesn't seem worth translating them into
  1818.         case SYM_POST_DECREMENT: // += and -= at load-time or during the tokenizing phase higher above because 
  1819.         case SYM_PRE_INCREMENT:  // it might introduce precedence problems, plus the post-inc/dec's nature is
  1820.         case SYM_PRE_DECREMENT:  // unique among all the operators in that it pushes an operand before the evaluation.
  1821.             is_pre_op = (this_token.symbol >= SYM_PRE_INCREMENT); // Store this early because its symbol will soon be overwritten.
  1822.             if (right.symbol != SYM_VAR || right_is_number == PURE_NOT_NUMERIC) // Invalid operation.
  1823.             {
  1824.                 if (right.symbol == SYM_VAR) // Thus due to the above check, it's a non-numeric target such as ++i when "i" is blank or contains text. This line was fixed in v1.0.46.16.
  1825.                 {
  1826.                     right.var->Assign(); // If target var contains "" or "non-numeric text", make it blank. Clipboard is also supported here.
  1827.                     if (is_pre_op)
  1828.                     {
  1829.                         // v1.0.46.01: For consistency, it seems best to make the result of a pre-op be a
  1830.                         // variable whenever a variable came in.  This allows its address to be taken, and it
  1831.                         // to be passed byreference, and other SYM_VAR behaviors, even if the operation itself
  1832.                         // produces a blank value.
  1833.                         // KNOWN LIMITATION: Although this behavior is convenient to have have, I realize now
  1834.                         // that it produces at least one weird effect: whenever a binary operator's operands
  1835.                         // both use a pre-op on the same variable, or whenever two or more of a function-call's
  1836.                         // parameters both do a pre-op on the same variable, that variable will have the same
  1837.                         // value at the time the binary operator or function-call is evaluated.  For example:
  1838.                         //    y = 1
  1839.                         //    x = ++y + ++y  ; Yields 6 not 5.
  1840.                         // However, if you think about the situations anyone would intentionally want to do
  1841.                         // the above or a function-call with two or more pre-ops in its parameters, it seems
  1842.                         // so extremely rare that retaining the existing behavior might be superior because of:
  1843.                         // 1) Convenience: It allows ++x to be passed ByRef, it's address taken.  Less importantly,
  1844.                         //    it also allows ++++x to work.
  1845.                         // 2) Backward compatibility: Some existing scripts probably already rely on the fact that
  1846.                         //    ++x and --x produce an lvalue (though it's undocumented).
  1847.                         if (right.var->Type() == VAR_NORMAL)
  1848.                         {
  1849.                             this_token.var = right.var;  // Make the result a variable rather than a normal operand so that its
  1850.                             this_token.symbol = SYM_VAR; // address can be taken, and it can be passed ByRef. e.g. &(++x)
  1851.                             break;
  1852.                         }
  1853.                         //else VAR_CLIPBOARD, which is allowed in only when it's the lvalue of an assignent or
  1854.                         // inc/dec.  So fall through to make the result blank because clipboard isn't allowed as
  1855.                         // SYM_VAR beyond this point (to simplify the code and improve maintainability).
  1856.                     }
  1857.                     //else post_op against non-numeric target-var.  Fall through to below to yield blank result.
  1858.                 }
  1859.                 //else target isn't a var.  Fall through to below to yield blank result.
  1860.                 this_token.marker = "";          // Make the result blank to indicate invalid operation
  1861.                 this_token.symbol = SYM_STRING;  // (assign to non-lvalue or increment/decrement a non-number).
  1862.                 break;
  1863.             } // end of "invalid operation" block.
  1864.  
  1865.             // DUE TO CODE SIZE AND PERFORMANCE decided not to support things like the following:
  1866.             // -> ++++i ; This one actually works because pre-ops produce a variable (usable by future pre-ops).
  1867.             // -> i++++ ; Fails because the first ++ produces an operand that isn't a variable.  It could be
  1868.             //    supported via a cascade loop here to pull all remaining consective post/pre ops out of
  1869.             //    the postfix array and apply them to "delta", but it just doesn't seem worth it.
  1870.             // -> --Var++ ; Fails because ++ has higher precedence than --, but it produces an operand that isn't
  1871.             //    a variable, so the "--" fails.  Things like --Var++ seem pointless anyway because they seem
  1872.             //    nearly identical to the sub-expression (Var+1)? Anyway, --Var++ could probably be supported
  1873.             //    using the loop described in the previous example.
  1874.             delta = (this_token.symbol == SYM_POST_INCREMENT || this_token.symbol == SYM_PRE_INCREMENT) ? 1 : -1;
  1875.             if (right_is_number == PURE_INTEGER)
  1876.             {
  1877.                 this_token.value_int64 = (right.symbol == SYM_INTEGER) ? right.value_int64 : ATOI64(right_contents);
  1878.                 right.var->Assign(this_token.value_int64 + delta);
  1879.             }
  1880.             else // right_is_number must be PURE_FLOAT because it's the only remaining alternative.
  1881.             {
  1882.                 // Uses atof() because no need to have the overhead of ATOF() since PURE_FLOAT is never hex.
  1883.                 this_token.value_double = (right.symbol == SYM_FLOAT) ? right.value_double : atof(right_contents);
  1884.                 right.var->Assign(this_token.value_double + delta);
  1885.             }
  1886.             if (is_pre_op)
  1887.             {
  1888.                 // Push the variable itself so that the operation will have already taken effect for whoever
  1889.                 // uses this operand/result in the future (i.e. pre-op vs. post-op).
  1890.                 if (right.var->Type() == VAR_NORMAL)
  1891.                 {
  1892.                     this_token.var = right.var;  // Make the result a variable rather than a normal operand so that its
  1893.                     this_token.symbol = SYM_VAR; // address can be taken, and it can be passed ByRef. e.g. &(++x)
  1894.                 }
  1895.                 else // VAR_CLIPBOARD, which is allowed in only when it's the lvalue of an assignent or inc/dec.
  1896.                 {
  1897.                     // Clipboard isn't allowed as SYM_VAR beyond this point (to simplify the code and
  1898.                     // improve maintainability).  So use the new contents of the clipboard as the result,
  1899.                     // rather than the clipboard itself.
  1900.                     if (right_is_number == PURE_INTEGER)
  1901.                         this_token.value_int64 += delta;
  1902.                     else // right_is_number must be PURE_FLOAT because it's the only alternative remaining.
  1903.                         this_token.value_double += delta;
  1904.                     this_token.symbol = right_is_number; // Set the symbol type to match the double or int64 that was already stored higher above.
  1905.                 }
  1906.             }
  1907.             else // Post-inc/dec, so the non-delta version, which was already stored in this_token, should get pushed.
  1908.                 this_token.symbol = right_is_number; // Set the symbol type to match the double or int64 that was already stored higher above.
  1909.             break;
  1910.  
  1911.         case SYM_ADDRESS: // Take the address of a variable.
  1912.             if (right.symbol == SYM_VAR) // At this stage, SYM_VAR is always a normal variable, never a built-in one, so taking its address should be safe.
  1913.             {
  1914.                 this_token.symbol = SYM_INTEGER;
  1915.                 this_token.value_int64 = (__int64)right_contents;
  1916.             }
  1917.             else // Invalid, so make it a localized blank value.
  1918.             {
  1919.                 this_token.marker = "";
  1920.                 this_token.symbol = SYM_STRING;
  1921.             }
  1922.             break;
  1923.  
  1924.         case SYM_DEREF:   // Dereference an address to retrieve a single byte.
  1925.         case SYM_BITNOT:           // The tilde (~) operator.
  1926.             if (right_is_number == PURE_INTEGER) // But in this case, it can be hex, so use ATOI64().
  1927.                 right_int64 = right.symbol == SYM_INTEGER ? right.value_int64 : ATOI64(right_contents);
  1928.             else if (right_is_number == PURE_FLOAT)
  1929.                 // No need to have the overhead of ATOI64() since PURE_FLOAT can't be hex:
  1930.                 right_int64 = right.symbol == SYM_FLOAT ? (__int64)right.value_double : _atoi64(right_contents);
  1931.             else // String.  Seems best to consider the application of unary minus to a string, even a quoted string literal such as "15", to be a failure.
  1932.             {
  1933.                 this_token.marker = "";
  1934.                 this_token.symbol = SYM_STRING;
  1935.                 break;
  1936.             }
  1937.             // Since above didn't "break":
  1938.             if (this_token.symbol == SYM_BITNOT)
  1939.             {
  1940.                 // Note that it is not legal to perform ~, &, |, or ^ on doubles.  Because of this, and also to
  1941.                 // conform to the behavior of the Transform command, any floating point operand is truncated to
  1942.                 // an integer above.
  1943.                 if (right_int64 < 0 || right_int64 > UINT_MAX)
  1944.                     this_token.value_int64 = ~right_int64;
  1945.                 else // See comments at TRANS_CMD_BITNOT for why it's done this way:
  1946.                     this_token.value_int64 = (size_t)~(DWORD)right_int64; // Casting this way avoids compiler warning.
  1947.             }
  1948.             else // SYM_DEREF
  1949.             {
  1950.                 // Reasons for resolving *Var to a number rather than a single-char string:
  1951.                 // 1) More consistent with future uses of * that might operate on the address of 2-byte,
  1952.                 //    4-byte, and 8-byte targets.
  1953.                 // 2) Performs better in things like ExtractInteger() that would otherwise have to call Asc().
  1954.                 // 3) Converting it to a one-char string would add no value beyond convenience because script
  1955.                 //    could do "if (*var = 65)" if it's concerned with avoiding a Chr() call for performance
  1956.                 //    reasons.  Also, it seems somewhat rare that a script will access a string's characters
  1957.                 //    one-by-one via the * method because that a parsing loop can already do that more easily.
  1958.                 // 4) Reduces code size and improves performance (however, the single-char string method would
  1959.                 //    use _alloca(2) to get some temporary memory, so it wouldn't be too bad in performance).
  1960.                 //
  1961.                 // The following does a basic bounds check to prevent crashes due to dereferencing addresses
  1962.                 // that are obviously bad.  In terms of percentage impact on performance, this seems quite
  1963.                 // justified.  In the future, could also put a __try/__except block around this (like DllCall
  1964.                 // uses) to prevent buggy scripts from crashing.  In addition to ruling out the dereferencing of
  1965.                 // a NULL address, the >255 check also rules out common-bug addresses (I don't think addresses
  1966.                 // this low can realistically ever be legitimate, but it would be nice to get confirmation).
  1967.                 // For simplicity and due to rarity, a zero is yielded in such cases rather than an empty string.
  1968.                 this_token.value_int64 = (right_int64 < 256 || right_int64 > 0xFFFFFFFF)
  1969.                     ? 0 : this_token.value_int64 = *(UCHAR *)right_int64; // Dereference to extract one unsigned character, just like Asc().
  1970.             }
  1971.             this_token.symbol = SYM_INTEGER; // Must be done only after its old value was used above. v1.0.36.07: Fixed to be SYM_INTEGER vs. right_is_number for SYM_BITNOT.
  1972.             break;
  1973.  
  1974.         default: // NON-UNARY OPERATOR.
  1975.             // GET THE SECOND (LEFT-SIDE) OPERAND FOR THIS OPERATOR:
  1976.             if (!stack_count) // Prevent stack underflow.
  1977.                 goto abnormal_end;
  1978.             ExprTokenType &left = *STACK_POP; // i.e. the right operand always comes off the stack before the left.
  1979.             if (!IS_OPERAND(left.symbol)) // Haven't found a way to produce this situation yet, but safe to assume it's possible.
  1980.                 goto abnormal_end;
  1981.  
  1982.             if (IS_ASSIGNMENT_EXCEPT_POST_AND_PRE(this_token.symbol)) // v1.0.46: Added support for various assignment operators.
  1983.             {
  1984.                 if (left.symbol != SYM_VAR)
  1985.                 {
  1986.                     this_token.marker = "";          // Make the result blank to indicate invalid operation
  1987.                     this_token.symbol = SYM_STRING;  // (assign to non-lvalue).
  1988.                     break; // Equivalent to "goto push_this_token" in this case.
  1989.                 }
  1990.                 switch(this_token.symbol)
  1991.                 {
  1992.                 case SYM_ASSIGN: // Listed first for performance (it's probably the most common because things like ++ and += aren't expressions when they're by themselves on a line).
  1993.                     left.var->Assign(right); // left.var can be VAR_CLIPBOARD in this case.
  1994.                     if (left.var->Type() == VAR_CLIPBOARD) // v1.0.46.01: Clipboard is present as SYM_VAR, but only for assign-to-clipboard so that built-in functions and other code sections don't need handling for VAR_CLIPBOARD.
  1995.                     {
  1996.                         circuit_token = this_token.circuit_token; // Temp copy to avoid overwrite by the next line.
  1997.                         this_token = right; // Struct copy.  Doing it this way is more maintainable than other methods, and is unlikely to perform much worse.
  1998.                         this_token.circuit_token = circuit_token;
  1999.                     }
  2000.                     else
  2001.                     {
  2002.                         this_token.var = left.var;   // Make the result a variable rather than a normal operand so that its
  2003.                         this_token.symbol = SYM_VAR; // address can be taken, and it can be passed ByRef. e.g. &(x:=1)
  2004.                     }
  2005.                     goto push_this_token;
  2006.                 case SYM_ASSIGN_ADD:           this_token.symbol = SYM_ADD; break;
  2007.                 case SYM_ASSIGN_SUBTRACT:      this_token.symbol = SYM_SUBTRACT; break;
  2008.                 case SYM_ASSIGN_MULTIPLY:      this_token.symbol = SYM_MULTIPLY; break;
  2009.                 case SYM_ASSIGN_DIVIDE:        this_token.symbol = SYM_DIVIDE; break;
  2010.                 case SYM_ASSIGN_FLOORDIVIDE:   this_token.symbol = SYM_FLOORDIVIDE; break;
  2011.                 case SYM_ASSIGN_BITOR:         this_token.symbol = SYM_BITOR; break;
  2012.                 case SYM_ASSIGN_BITXOR:        this_token.symbol = SYM_BITXOR; break;
  2013.                 case SYM_ASSIGN_BITAND:        this_token.symbol = SYM_BITAND; break;
  2014.                 case SYM_ASSIGN_BITSHIFTLEFT:  this_token.symbol = SYM_BITSHIFTLEFT; break;
  2015.                 case SYM_ASSIGN_BITSHIFTRIGHT: this_token.symbol = SYM_BITSHIFTRIGHT; break;
  2016.                 case SYM_ASSIGN_CONCAT:        this_token.symbol = SYM_CONCAT; break;
  2017.                 }
  2018.                 // Since above didn't goto/break, this is an assignment other than SYM_ASSIGN, so it needs further
  2019.                 // evaluation later below before the assignment will actually be made.
  2020.                 sym_assign_var = left.var; // This tells the bottom of this switch() to do extra steps for this assignment.
  2021.             }
  2022.  
  2023.             // The following section needs done even for assignments such as += because the type of value
  2024.             // inside the target variable (integer vs. float vs. string) must be known to determine how
  2025.             // the operation should proceed.
  2026.             // Since above didn't goto/break, this is a non-unary operator that needs further processing.
  2027.             // If the operand is still generic/undetermined, find out whether it is a string, integer, or float:
  2028.             switch(left.symbol)
  2029.             {
  2030.             case SYM_VAR:
  2031.                 left_contents = left.var->Contents();
  2032.                 left_is_number = IsPureNumeric(left_contents, true, false, true);
  2033.                 break;
  2034.             case SYM_OPERAND:
  2035.                 left_contents = left.marker;
  2036.                 left_is_number = IsPureNumeric(left_contents, true, false, true);
  2037.                 break;
  2038.             case SYM_STRING:
  2039.                 left_contents = left.marker;
  2040.                 left_is_number = PURE_NOT_NUMERIC;
  2041.             default:
  2042.                 // left_contents is left uninitialized for performance and to catch bugs.
  2043.                 left_is_number = left.symbol;
  2044.             }
  2045.  
  2046.             if (!right_is_number || !left_is_number || this_token.symbol == SYM_CONCAT)
  2047.             {
  2048.                 // Above check has ensured that at least one of them is a string.  But the other
  2049.                 // one might be a number such as in 5+10="15", in which 5+10 would be a numerical
  2050.                 // result being compared to the raw string literal "15".
  2051.                 switch (right.symbol)
  2052.                 {
  2053.                 // Seems best to obey SetFormat for these two, though it's debatable:
  2054.                 case SYM_INTEGER: right_string = ITOA64(right.value_int64, right_buf); break;
  2055.                 case SYM_FLOAT: snprintf(right_buf, sizeof(right_buf), g.FormatFloat, right.value_double); right_string = right_buf; break;
  2056.                 default: right_string = right_contents; // SYM_STRING/SYM_OPERAND/SYM_VAR, which is already in the right format.
  2057.                 }
  2058.  
  2059.                 switch (left.symbol)
  2060.                 {
  2061.                 // Seems best to obey SetFormat for these two, though it's debatable:
  2062.                 case SYM_INTEGER: left_string = ITOA64(left.value_int64, left_buf); break;
  2063.                 case SYM_FLOAT: snprintf(left_buf, sizeof(left_buf), g.FormatFloat, left.value_double); left_string = left_buf; break;
  2064.                 default: left_string = left_contents; // SYM_STRING/SYM_OPERAND/SYM_VAR, which is already in the right format.
  2065.                 }
  2066.  
  2067.                 result_symbol = SYM_INTEGER; // Set default.  Boolean results are treated as integers.
  2068.                 switch(this_token.symbol)
  2069.                 {
  2070.                 case SYM_EQUAL:     this_token.value_int64 = !((g.StringCaseSense == SCS_INSENSITIVE)
  2071.                                         ? stricmp(left_string, right_string)
  2072.                                         : lstrcmpi(left_string, right_string)); break; // i.e. use the "more correct mode" except when explicitly told to use the fast mode (v1.0.43.03).
  2073.                 case SYM_EQUALCASE: this_token.value_int64 = !strcmp(left_string, right_string); break; // Case sensitive.
  2074.                 // The rest all obey g.StringCaseSense since they have no case sensitive counterparts:
  2075.                 case SYM_NOTEQUAL:  this_token.value_int64 = g_strcmp(left_string, right_string) ? 1 : 0; break;
  2076.                 case SYM_GT:        this_token.value_int64 = g_strcmp(left_string, right_string) > 0; break;
  2077.                 case SYM_LT:        this_token.value_int64 = g_strcmp(left_string, right_string) < 0; break;
  2078.                 case SYM_GTOE:      this_token.value_int64 = g_strcmp(left_string, right_string) > -1; break;
  2079.                 case SYM_LTOE:      this_token.value_int64 = g_strcmp(left_string, right_string) < 1; break;
  2080.  
  2081.                 case SYM_CONCAT:
  2082.                     // Even if the left or right is "", must copy the result to temporary memory, at least
  2083.                     // when integers and floats had to be converted to temporary strings above.
  2084.                     // Binary clipboard is ignored because it's documented that except for certain features,
  2085.                     // binary clipboard variables are seen only up to the first binary zero (mostly to
  2086.                     // simplify the code).
  2087.                     right_length = (right.symbol == SYM_VAR) ? right.var->LengthIgnoreBinaryClip() : strlen(right_string);
  2088.                     if (sym_assign_var // Since "right" is being appended onto a variable ("left"), an optimization is possible.
  2089.                         && sym_assign_var->AppendIfRoom(right_string, (VarSizeType)right_length)) // But only if the target variable has enough remaining capacity.
  2090.                     {
  2091.                         // AppendIfRoom() always fails for VAR_CLIPBOARD, so below won't execute for it (which is
  2092.                         // good because don't want clipboard to stay as SYM_VAR after the assignment. This is
  2093.                         // because it simplifies the code not to have to worry about VAR_CLIPBOARD in BIFs, etc.)
  2094.                         this_token.var = sym_assign_var; // Make the result a variable rather than a normal operand so that its
  2095.                         this_token.symbol = SYM_VAR;     // address can be taken, and it can be passed ByRef. e.g. &(x+=1)
  2096.                         goto push_this_token; // Skip over all other sections such as subsequent checks of sym_assign_var because it was all taken care of here.
  2097.                     }
  2098.                     // Otherwise, fall back to the other concat methods:
  2099.                     left_length = (left.symbol == SYM_VAR) ? left.var->LengthIgnoreBinaryClip() : strlen(left_string);
  2100.                     result_size = right_length + left_length + 1;
  2101.  
  2102.                     if (output_var && EXPR_IS_DONE) // i.e. this is ACT_ASSIGNEXPR and we're at the final operator, a concat.
  2103.                         temp_var = output_var;
  2104.                     else if (i < postfix_count-1 && postfix[i+1]->symbol == SYM_ASSIGN // Next operation is ":=".
  2105.                         && stack_count && stack[stack_count-1]->symbol == SYM_VAR // i.e. let the next iteration handle it instead of doing it here.  Further below relies on this having been checked.
  2106.                         && stack[stack_count-1]->var->Type() == VAR_NORMAL) // Don't do clipboard here because: 1) AcceptNewMem() doesn't support it; 2) Could probably use Assign() and then make its result be a newly added mem_count item, but the code complexity doesn't seem worth it given the rarity.
  2107.                         temp_var = stack[stack_count-1]->var;
  2108.                     else
  2109.                         temp_var = NULL;
  2110.  
  2111.                     if (temp_var)
  2112.                     {
  2113.                         result = temp_var->Contents();
  2114.                         if (result == left_string) // This is something like x := x . y, so simplify it to x .= y
  2115.                         {
  2116.                             // MUST DO THE ABOVE CHECK because the next section further below might free the
  2117.                             // destination memory before doing the operation. Thus, if the destination is the
  2118.                             // same as one of the sources, freeing it beforehand would obviously be a problem.
  2119.                             if (temp_var->AppendIfRoom(right_string, (VarSizeType)right_length))
  2120.                             {
  2121.                                 if (temp_var == output_var)
  2122.                                     goto normal_end_skip_output_var; // Nothing more to do because it has even taken care of output_var already.
  2123.                                 else // temp_var is from look-ahead to a future assignment.
  2124.                                 {
  2125.                                     this_token.circuit_token = postfix[++i]->circuit_token; // this_token.circuit_token should have been NULL prior to this because the final right-side result of an assignment shouldn't be the last item of an AND/OR/IFF's left branch. The assignment itself would be that.
  2126.                                     this_token.var = STACK_POP->var; // Make the result a variable rather than a normal operand so that its
  2127.                                     this_token.symbol = SYM_VAR;     // address can be taken, and it can be passed ByRef. e.g. &(x:=1)
  2128.                                     goto push_this_token;
  2129.                                 }
  2130.                             }
  2131.                             //else no optimizations are possible because: 1) No room; 2) The overlap between the
  2132.                             // source and dest requires temporary memory.  So fall through to the slower method.
  2133.                         }
  2134.                         else if (result != right_string) // No overlap between the two sources and dest.
  2135.                         {
  2136.                             // The check above assumes that only a complete equality/overlap is possible,
  2137.                             // not a partial overlap.  A partial overlap between the memory of two variables
  2138.                             // seems impossible for a script to produce.  But if it ever does happen, the
  2139.                             // Assign() below would free part or all of one of the sources before doing
  2140.                             // the concat, which would corrupt the result.
  2141.                             // Optimize by copying directly into the target variable rather than the intermediate
  2142.                             // step of putting into temporary memory.
  2143.                             if (!temp_var->Assign(NULL, (VarSizeType)result_size - 1)) // Resize the destination, if necessary.
  2144.                                 goto abort; // Above should have already reported the error.
  2145.                             result = temp_var->Contents(); // Call Contents() AGAIN because Assign() may have changed it.
  2146.                             if (left_length)
  2147.                                 memcpy(result, left_string, left_length);  // Not +1 because don't need the zero terminator.
  2148.                             memcpy(result + left_length, right_string, right_length + 1); // +1 to include its zero terminator.
  2149.                             temp_var->Close(); // Mostly just to reset the VAR_ATTRIB_BINARY_CLIP attribute and for maintainability.
  2150.                             if (temp_var == output_var)
  2151.                                 goto normal_end_skip_output_var; // Nothing more to do because it has even taken care of output_var already.
  2152.                             else // temp_var is from look-ahead to a future assignment.
  2153.                             {
  2154.                                 this_token.circuit_token = postfix[++i]->circuit_token; // this_token.circuit_token should have been NULL prior to this because the final right-side result of an assignment shouldn't be the last item of an AND/OR/IFF's left branch. The assignment itself would be that.
  2155.                                 this_token.var = STACK_POP->var; // Make the result a variable rather than a normal operand so that its
  2156.                                 this_token.symbol = SYM_VAR;     // address can be taken, and it can be passed ByRef. e.g. &(x:=1)
  2157.                                 goto push_this_token;
  2158.                             }
  2159.                         }
  2160.                         //else result==right_string (e.g. x := y . x).  Although this could be optimized by 
  2161.                         // moving memory around inside output_var (if it has enough capacity), it seems more
  2162.                         // complicated than it's worth given the rarity of this.  It probably wouldn't save
  2163.                         // much time anyway due to the memory-moves inside output_var.  So just fall through
  2164.                         // to the normal method.
  2165.                     } // if (temp_var)
  2166.  
  2167.                     // Since above didn't "goto", it didn't find a way to optimize this concat.
  2168.                     // So fall back to the standard method.
  2169.                     // The following section is similar to the one for "symbol == SYM_FUNC", so they
  2170.                     // should be maintained together.
  2171.                     // The following isn't done because there's a memcpy() further below which would also
  2172.                     // have to check it, which hurts maintainability.  This doesn't seem worth it since
  2173.                     // it's unlikely to be the empty string in the case of concat.
  2174.                     //if (result_size == 1)
  2175.                     //    this_token.marker = "";
  2176.                     //else
  2177.                     // Must cast to int to avoid loss of negative values:
  2178.                     if (result_size <= (int)(aDerefBufSize - (target - aDerefBuf))) // There is room at the end of our deref buf, so use it.
  2179.                     {
  2180.                         this_token.marker = target;
  2181.                         target += result_size;  // Adjust target for potential future use by another concat or functionc call.
  2182.                     }
  2183.                     else if (result_size < EXPR_SMALL_MEM_LIMIT && alloca_usage < EXPR_ALLOCA_LIMIT) // See comments at EXPR_SMALL_MEM_LIMIT.
  2184.                     {
  2185.                         this_token.marker = (char *)_alloca(result_size);
  2186.                         alloca_usage += result_size; // This might put alloca_usage over the limit by as much as EXPR_SMALL_MEM_LIMIT, but that is fine because it's more of a guideline than a limit.
  2187.                     }
  2188.                     else // Need to create some new persistent memory for our temporary use.
  2189.                     {
  2190.                         // See the nearly identical section higher above for comments:
  2191.                         if (mem_count == MAX_EXPR_MEM_ITEMS // No more slots left (should be nearly impossible).
  2192.                             || !(this_token.marker = mem[mem_count] = (char *)malloc(result_size)))
  2193.                         {
  2194.                             LineError(ERR_OUTOFMEM ERR_ABORT);
  2195.                             goto abort;
  2196.                         }
  2197.                         ++mem_count;
  2198.                     }
  2199.                     if (left_length)
  2200.                         memcpy(this_token.marker, left_string, left_length);  // Not +1 because don't need the zero terminator.
  2201.                     memcpy(this_token.marker + left_length, right_string, right_length + 1); // +1 to include its zero terminator.
  2202.  
  2203.                     // For this new concat operator introduced in v1.0.31, it seems best to treat the
  2204.                     // result as a SYM_STRING if either operand is a SYM_STRING.  That way, when the
  2205.                     // result of the operation is later used, it will be a real string even if pure numeric,
  2206.                     // which allows an exact string match to be specified even when the inputs are
  2207.                     // technically numeric; e.g. the following should be true only if (Var . 33 = "1133") 
  2208.                     result_symbol = (left.symbol == SYM_STRING || right.symbol == SYM_STRING) ? SYM_STRING: SYM_OPERAND;
  2209.                     break;
  2210.  
  2211.                 default:
  2212.                     // Other operators do not support string operands, so the result is an empty string.
  2213.                     this_token.marker = "";
  2214.                     result_symbol = SYM_STRING;
  2215.                 }
  2216.                 this_token.symbol = result_symbol; // Must be done only after the switch() above.
  2217.             }
  2218.  
  2219.             else if (right_is_number == PURE_INTEGER && left_is_number == PURE_INTEGER && this_token.symbol != SYM_DIVIDE
  2220.                 || this_token.symbol <= SYM_BITSHIFTRIGHT && this_token.symbol >= SYM_BITOR) // Check upper bound first for short-circuit performance (because operators like +-*/ are much more frequently used).
  2221.             {
  2222.                 // Because both are integers and the operation isn't division, the result is integer.
  2223.                 // The result is also an integer for the bitwise operations listed in the if-statement
  2224.                 // above.  This is because it is not legal to perform ~, &, |, or ^ on doubles, and also
  2225.                 // because this behavior conforms to that of the Transform command.  Any floating point
  2226.                 // operands are truncated to integers prior to doing the bitwise operation.
  2227.  
  2228.                 switch (right.symbol)
  2229.                 {
  2230.                 case SYM_INTEGER: right_int64 = right.value_int64; break;
  2231.                 case SYM_FLOAT: right_int64 = (__int64)right.value_double; break;
  2232.                 default: right_int64 = ATOI64(right_contents); // SYM_OPERAND or SYM_VAR
  2233.                 // It can't be SYM_STRING because in here, both right and left are known to be numbers
  2234.                 // (otherwise an earlier "else if" would have executed instead of this one).
  2235.                 }
  2236.  
  2237.                 switch (left.symbol)
  2238.                 {
  2239.                 case SYM_INTEGER: left_int64 = left.value_int64; break;
  2240.                 case SYM_FLOAT: left_int64 = (__int64)left.value_double; break;
  2241.                 default: left_int64 = ATOI64(left_contents); // SYM_OPERAND or SYM_VAR
  2242.                 // It can't be SYM_STRING because in here, both right and left are known to be numbers
  2243.                 // (otherwise an earlier "else if" would have executed instead of this one).
  2244.                 }
  2245.  
  2246.                 result_symbol = SYM_INTEGER; // Set default.
  2247.                 switch(this_token.symbol)
  2248.                 {
  2249.                 // The most common cases are kept up top to enhance performance if switch() is implemented as if-else ladder.
  2250.                 case SYM_ADD:      this_token.value_int64 = left_int64 + right_int64; break;
  2251.                 case SYM_SUBTRACT: this_token.value_int64 = left_int64 - right_int64; break;
  2252.                 case SYM_MULTIPLY: this_token.value_int64 = left_int64 * right_int64; break;
  2253.                 // A look at K&R confirms that relational/comparison operations and logical-AND/OR/NOT
  2254.                 // always yield a one or a zero rather than arbitrary non-zero values:
  2255.                 case SYM_EQUALCASE: // Same behavior as SYM_EQUAL for numeric operands.
  2256.                 case SYM_EQUAL:    this_token.value_int64 = left_int64 == right_int64; break;
  2257.                 case SYM_NOTEQUAL: this_token.value_int64 = left_int64 != right_int64; break;
  2258.                 case SYM_GT:       this_token.value_int64 = left_int64 > right_int64; break;
  2259.                 case SYM_LT:       this_token.value_int64 = left_int64 < right_int64; break;
  2260.                 case SYM_GTOE:     this_token.value_int64 = left_int64 >= right_int64; break;
  2261.                 case SYM_LTOE:     this_token.value_int64 = left_int64 <= right_int64; break;
  2262.                 case SYM_BITAND:   this_token.value_int64 = left_int64 & right_int64; break;
  2263.                 case SYM_BITOR:    this_token.value_int64 = left_int64 | right_int64; break;
  2264.                 case SYM_BITXOR:   this_token.value_int64 = left_int64 ^ right_int64; break;
  2265.                 case SYM_BITSHIFTLEFT:  this_token.value_int64 = left_int64 << right_int64; break;
  2266.                 case SYM_BITSHIFTRIGHT: this_token.value_int64 = left_int64 >> right_int64; break;
  2267.                 case SYM_FLOORDIVIDE:
  2268.                     // Since it's integer division, no need for explicit floor() of the result.
  2269.                     // Also, performance is much higher for integer vs. float division, which is part
  2270.                     // of the justification for a separate operator.
  2271.                     if (right_int64 == 0) // Divide by zero produces blank result (perhaps will produce exception if script's ever support exception handlers).
  2272.                     {
  2273.                         this_token.marker = "";
  2274.                         result_symbol = SYM_STRING;
  2275.                     }
  2276.                     else
  2277.                         this_token.value_int64 = left_int64 / right_int64;
  2278.                     break;
  2279.                 case SYM_POWER:
  2280.                     // Note: The function pow() in math.h adds about 28 KB of code size (uncompressed)!
  2281.                     // Even assuming pow() supports negative bases such as (-2)**2, its size is why it's not used.
  2282.                     // v1.0.44.11: With Laszlo's help, negative integer bases are now supported.
  2283.                     if (!left_int64 && right_int64 < 0) // In essense, this is divide-by-zero.
  2284.                     {
  2285.                         // Return a consistent result rather than something that varies:
  2286.                         this_token.marker = "";
  2287.                         result_symbol = SYM_STRING;
  2288.                     }
  2289.                     else // We have a valid base and exponent and both are integers, so the calculation will always have a defined result.
  2290.                     {
  2291.                         if (left_was_negative = (left_int64 < 0))
  2292.                             left_int64 = -left_int64; // Force a positive due to the limitiations of qmathPow().
  2293.                         this_token.value_double = qmathPow((double)left_int64, (double)right_int64);
  2294.                         if (left_was_negative && right_int64 % 2) // Negative base and odd exponent (not zero or even).
  2295.                             this_token.value_double = -this_token.value_double;
  2296.                         if (right_int64 < 0)
  2297.                             result_symbol = SYM_FLOAT; // Due to negative exponent, override to float like TRANS_CMD_POW.
  2298.                         else
  2299.                             this_token.value_int64 = (__int64)this_token.value_double;
  2300.                     }
  2301.                     break;
  2302.                 }
  2303.                 this_token.symbol = result_symbol; // Must be done only after the switch() above.
  2304.             }
  2305.  
  2306.             else // Since one or both operands are floating point (or this is the division of two integers), the result will be floating point.
  2307.             {
  2308.                 // For these two, use ATOF vs. atof so that if one of them is an integer to be converted
  2309.                 // to a float for the purpose of this calculation, hex will be supported:
  2310.                 switch (right.symbol)
  2311.                 {
  2312.                 case SYM_INTEGER: right_double = (double)right.value_int64; break;
  2313.                 case SYM_FLOAT: right_double = right.value_double; break;
  2314.                 default: right_double = ATOF(right_contents); // SYM_OPERAND or SYM_VAR
  2315.                 // It can't be SYM_STRING because in here, both right and left are known to be numbers.
  2316.                 }
  2317.  
  2318.                 switch (left.symbol)
  2319.                 {
  2320.                 case SYM_INTEGER: left_double = (double)left.value_int64; break;
  2321.                 case SYM_FLOAT: left_double = left.value_double; break;
  2322.                 default: left_double = ATOF(left_contents); // SYM_OPERAND or SYM_VAR
  2323.                 // It can't be SYM_STRING because in here, both right and left are known to be numbers.
  2324.                 }
  2325.  
  2326.                 result_symbol = IS_RELATIONAL_OPERATOR(this_token.symbol) ? SYM_INTEGER : SYM_FLOAT; // Set default. v1.0.47.01: Changed relational operators to yield integers vs. floats because it's more intuitive and traditional (might also make relational operators perform better).
  2327.                 switch(this_token.symbol)
  2328.                 {
  2329.                 case SYM_ADD:      this_token.value_double = left_double + right_double; break;
  2330.                 case SYM_SUBTRACT: this_token.value_double = left_double - right_double; break;
  2331.                 case SYM_MULTIPLY: this_token.value_double = left_double * right_double; break;
  2332.                 case SYM_DIVIDE:
  2333.                 case SYM_FLOORDIVIDE:
  2334.                     if (right_double == 0.0) // Divide by zero produces blank result (perhaps will produce exception if script's ever support exception handlers).
  2335.                     {
  2336.                         this_token.marker = "";
  2337.                         result_symbol = SYM_STRING;
  2338.                     }
  2339.                     else
  2340.                     {
  2341.                         this_token.value_double = left_double / right_double;
  2342.                         if (this_token.symbol == SYM_FLOORDIVIDE) // Like Python, the result is floor()'d, moving to the nearest integer to the left on the number line.
  2343.                             this_token.value_double = qmathFloor(this_token.value_double); // Result is always a double when at least one of the inputs was a double.
  2344.                     }
  2345.                     break;
  2346.                 case SYM_EQUALCASE: // Same behavior as SYM_EQUAL for numeric operands.
  2347.                 case SYM_EQUAL:    this_token.value_int64 = left_double == right_double; break;
  2348.                 case SYM_NOTEQUAL: this_token.value_int64 = left_double != right_double; break;
  2349.                 case SYM_GT:       this_token.value_int64 = left_double > right_double; break;
  2350.                 case SYM_LT:       this_token.value_int64 = left_double < right_double; break;
  2351.                 case SYM_GTOE:     this_token.value_int64 = left_double >= right_double; break;
  2352.                 case SYM_LTOE:     this_token.value_int64 = left_double <= right_double; break;
  2353.                 case SYM_POWER:
  2354.                     // v1.0.44.11: With Laszlo's help, negative bases are now supported as long as the exponent is not fractional.
  2355.                     // See the other SYM_POWER higher above for more details about below.
  2356.                     left_was_negative = (left_double < 0);
  2357.                     if (left_double == 0.0 && right_double < 0  // In essense, this is divide-by-zero.
  2358.                         || left_was_negative && qmathFmod(right_double, 1.0) != 0.0) // Negative base, but exponent isn't close enough to being an integer: unsupported (to simplify code).
  2359.                     {
  2360.                         this_token.marker = "";
  2361.                         result_symbol = SYM_STRING;
  2362.                     }
  2363.                     else
  2364.                     {
  2365.                         if (left_was_negative)
  2366.                             left_double = -left_double; // Force a positive due to the limitiations of qmathPow().
  2367.                         this_token.value_double = qmathPow(left_double, right_double);
  2368.                         if (left_was_negative && qmathFabs(qmathFmod(right_double, 2.0)) == 1.0) // Negative base and exactly-odd exponent (otherwise, it can only be zero or even because if not it would have returned higher above).
  2369.                             this_token.value_double = -this_token.value_double;
  2370.                     }
  2371.                     break;
  2372.                 } // switch(this_token.symbol)
  2373.                 this_token.symbol = result_symbol; // Must be done only after the switch() above.
  2374.             } // Result is floating point.
  2375.         } // switch() operator type
  2376.  
  2377.         if (sym_assign_var) // Added in v1.0.46. There are some places higher above that handle sym_assign_var themselves and skip this section via goto.
  2378.         {
  2379.             sym_assign_var->Assign(this_token); // Assign the result (based on its type) to the target variable.
  2380.             if (sym_assign_var->Type() != VAR_CLIPBOARD)
  2381.             {
  2382.                 this_token.var = sym_assign_var;    // Make the result a variable rather than a normal operand so that its
  2383.                 this_token.symbol = SYM_VAR;        // address can be taken, and it can be passed ByRef. e.g. &(x+=1)
  2384.             }
  2385.             //else its the clipboard, so just push this_token as-is because after its assignment is done,
  2386.             // VAR_CLIPBOARD should no longer be a SYM_VAR.  This is done to simplify the code, such as BIFs.
  2387.             //
  2388.             // Now fall through and push this_token onto the stack as an operand for use by future operators.
  2389.             // This is because by convention, an assignment like "x+=1" produces a usable operand.
  2390.         }
  2391.  
  2392. push_this_token:
  2393.         if (!this_token.circuit_token) // It's not capable of short-circuit.
  2394.             STACK_PUSH(&this_token);   // Push the result onto the stack for use as an operand by a future operator.
  2395.         else // This is the final result of an IFF's condition or a AND or OR's left branch.  Apply short-circuit boolean method to it.
  2396.         {
  2397. non_null_circuit_token:
  2398.             // Cast this left-branch result to true/false, then determine whether it should cause its
  2399.             // parent AND/OR/IFF to short-circuit.
  2400.  
  2401.             // If its a function result or raw numeric literal such as "if (123 or false)", its type might
  2402.             // still be SYM_OPERAND, so resolve that to distinguish between the any SYM_STRING "0"
  2403.             // (considered "true") and something that is allowed to be the number zero (which is
  2404.             // considered "false").  In other words, the only literal string (or operand made a
  2405.             // SYM_STRING via a previous operation) that is considered "false" is the empty string
  2406.             // (i.e. "0" doesn't qualify but 0 does):
  2407.             switch(this_token.symbol)
  2408.             {
  2409.             case SYM_VAR:
  2410.                 // "right" vs. "left" is used even though this is technically the left branch because
  2411.                 // right is used more often (for unary operators) and sometimes the compiler generates
  2412.                 // faster code for the most frequently accessed variables.
  2413.                 right_contents = this_token.var->Contents();
  2414.                 right_is_number = IsPureNumeric(right_contents, true, false, true);
  2415.                 break;
  2416.             case SYM_OPERAND:
  2417.                 right_contents = this_token.marker;
  2418.                 right_is_number = IsPureNumeric(right_contents, true, false, true);
  2419.                 break;
  2420.             case SYM_STRING:
  2421.                 right_contents = this_token.marker;
  2422.                 right_is_number = PURE_NOT_NUMERIC;
  2423.             default:
  2424.                 // right_contents is left uninitialized for performance and to catch bugs.
  2425.                 right_is_number = this_token.symbol;
  2426.             }
  2427.  
  2428.             switch (right_is_number)
  2429.             {
  2430.             case PURE_INTEGER: // Probably the most common, e.g. both sides of "if (x>3 and x<6)" are the number 1/0.
  2431.                 // Force it to be purely 1 or 0 if it isn't already.
  2432.                 left_branch_is_true = (this_token.symbol == SYM_INTEGER ? this_token.value_int64
  2433.                     : ATOI64(right_contents)) != 0;
  2434.                 break;
  2435.             case PURE_FLOAT: // Convert to float, not int, so that a number between 0.0001 and 0.9999 is is considered "true".
  2436.                 left_branch_is_true = (this_token.symbol == SYM_FLOAT ? this_token.value_double
  2437.                     : atof(right_contents)) != 0.0;
  2438.                 break;
  2439.             default:  // string.
  2440.                 // Since "if x" evaluates to false when x is blank, it seems best to also have blank
  2441.                 // strings resolve to false when used in more complex ways. In other words "if x or y"
  2442.                 // should be false if both x and y are blank.  Logical-not also follows this convention.
  2443.                 left_branch_is_true = (*right_contents != '\0');
  2444.             }
  2445.  
  2446.             if (this_token.circuit_token->symbol == SYM_IFF_THEN)
  2447.             {
  2448.                 if (!left_branch_is_true) // The ternary's condition is false.
  2449.                 {
  2450.                     // Discard the entire "then" branch of this ternary operator, leaving only the
  2451.                     // "else" branch to be evaluated later as the result.
  2452.                     // Ternaries nested inside each other don't need to be considered special for the purpose
  2453.                     // of discarding ternary branches due to the very nature of postfix (i.e. it's already put
  2454.                     // nesting in the right postfix order to support this method of discarding a branch).
  2455.                     for (++i; postfix[i] != this_token.circuit_token; ++i); // Should always be found, so no need to check postfix_count.
  2456.                     // The outer loop will now do a ++i to discard the SYM_IFF_THEN itself.
  2457.                 }
  2458.                 //else the ternary's condition is true.  Do nothing; just let the next iteration evaluate the
  2459.                 // THEN portion and then treat the SYM_IFF_THEN it encounters as a unary operator (after that,
  2460.                 // it will discard the ELSE branch).
  2461.                 continue;
  2462.             }
  2463.             // Since above didn't "continue", this_token is the left branch of an AND/OR.  Check for short-circuit.
  2464.             // The following loop exists to support cascading short-circuiting such as the following example:
  2465.             // 2>3 and 2>3 and 2>3
  2466.             // In postfix notation, the above looks like:
  2467.             // 2 3 > 2 3 > and 2 3 > and
  2468.             // When the first '>' operator is evaluated to false, it sees that its parent is an AND and
  2469.             // thus it short-circuits, discarding everything between the first '>' and the "and".
  2470.             // But since the first and's parent is the second "and", that false result just produced is now
  2471.             // the left branch of the second "and", so the loop conducts a second iteration to discard
  2472.             // everything between the first "and" and the second.  By contrast, if the second "and" were
  2473.             // an "or", the second iteration would never occur because the loop's condition would be false
  2474.             // on the second iteration, which would then cause the first and's false value to be discarded
  2475.             // (due to the loop ending without having PUSHed) because solely the right side of the "or" should
  2476.             // determine the final result of the "or".
  2477.             //
  2478.             // The following code is probably equivalent to the loop below it.  However, it's only slightly
  2479.             // smaller in code size when you examine what it actually does, and it almost certainly performs
  2480.             // slightly worse because the "goto" incurs unnecessary steps such as recalculating left_branch_is_true.
  2481.             // Therefore, it doesn't seem worth changing it:
  2482.             //if (left_branch_is_true == (this_token.circuit_token->symbol == SYM_OR)) // If true, this AND/OR causes a short-circuit
  2483.             //{
  2484.             //    for (++i; postfix[i] != this_token.circuit_token; ++i); // Should always be found, so no need to check postfix_count.
  2485.             //    this_token.symbol = SYM_INTEGER;
  2486.             //    this_token.value_int64 = left_branch_is_true; // Assign a pure 1 (for SYM_OR) or 0 (for SYM_AND).
  2487.             //    this_token.circuit_token = postfix[i]->circuit_token; // In case circuit_token == SYM_IFF_THEN.
  2488.             //    goto push_this_token; // In lieu of STACK_PUSH(this_token) in case circuit_token == SYM_IFF_THEN.
  2489.             //}
  2490.             for (circuit_token = this_token.circuit_token
  2491.                 ; left_branch_is_true == (circuit_token->symbol == SYM_OR);) // If true, this AND/OR causes a short-circuit
  2492.             {
  2493.                 // Discard the entire right branch of this AND/OR:
  2494.                 for (++i; postfix[i] != circuit_token; ++i); // Should always be found, so no need to check postfix_count.
  2495.                 // Above loop is self-contained.
  2496.                 if (   !(circuit_token = postfix[i]->circuit_token) // This value is also used by our loop's condition. Relies on short-circuit boolean order with the below.
  2497.                     || circuit_token->symbol == SYM_IFF_THEN   ) // Don't cascade from AND/OR into IFF because IFF requires a different cascade approach that's implemented only after its winning branch is evaluated.  Otherwise, things like "0 and 1 ? 3 : 4" wouldn't work.
  2498.                 {
  2499.                     // No more cascading is needed because this AND/OR isn't the left branch of another.
  2500.                     // This will be the final result of this AND/OR because it's right branch was discarded
  2501.                     // above without having been evaluated nor any of its functions called.  It's safe to use
  2502.                     // this_token vs. postfix[i] below, for performance, because the value in its circuit_token
  2503.                     // member no longer matters:
  2504.                     this_token.symbol = SYM_INTEGER;
  2505.                     this_token.value_int64 = left_branch_is_true; // Assign a pure 1 (for SYM_OR) or 0 (for SYM_AND).
  2506.                     this_token.circuit_token = circuit_token; // In case circuit_token == SYM_IFF_THEN.
  2507.                     goto push_this_token; // In lieu of STACK_PUSH(this_token) in case circuit_token == SYM_IFF_THEN.
  2508.                 }
  2509.                 //else there is more cascading to be checked, so continue looping.
  2510.             }
  2511.             // If the loop ends normally (not via "break"), postfix[i] is now the left branch of an
  2512.             // AND/OR that should not short-circuit.  As a result, this left branch is simply discarded
  2513.             // (by means of the outer loop's ++i) because its right branch will be the sole determination
  2514.             // of whether this AND/OR is true or false.
  2515.         } // Short-circuit (left branch of an AND/OR).
  2516.     } // For each item in the postfix array.
  2517.  
  2518.     // Although ACT_EXPRESSION was already checked higher above for function calls, there are other ways besides
  2519.     // an isolated function call to have ACT_EXPRESSION.  For example: var&=3 (where &= is an operator that lacks
  2520.     // a corresponding command).  Another example: true ? fn1() : fn2()
  2521.     // Also, there might be ways the function-call section didn't return for ACT_EXPRESSION, such as when somehow
  2522.     // there was more than one token on the stack even for the final function call, or maybe other unforeseen ways.
  2523.     // It seems best to avoid any chance of looking at the result since it might be invalid due to the above
  2524.     // having taken shortcuts (since it knew the result would be discarded).
  2525.     if (mActionType == ACT_EXPRESSION)   // A stand-alone expression whose end result doesn't matter.
  2526.         goto normal_end_skip_output_var; // Can't be any output_var for this action type. Also, leave result_to_return at its default of "".
  2527.  
  2528.     if (stack_count != 1)  // Even for multi-statement expressions, the stack should have only one item left on it:
  2529.         goto abnormal_end; // the overall result. Examples of errors include: () ... x y ... (x + y) (x + z) ... etc. (some of these might no longer produce this issue due to auto-concat).
  2530.  
  2531.     ExprTokenType &result_token = *stack[0];  // For performance and convenience.  Even for multi-statement, the bottommost item on the stack is the final result so that things like var1:=1,var2:=2 work.
  2532.  
  2533.     // Store the result of the expression in the deref buffer for the caller.  It is stored in the current
  2534.     // format in effect via SetFormat because:
  2535.     // 1) The := operator then doesn't have to convert to int/double then back to string to put the right format into effect.
  2536.     // 2) It might add a little bit of flexibility in places parameters where floating point values are expected
  2537.     //    (i.e. it allows a way to do automatic rounding), without giving up too much.  Changing floating point
  2538.     //    precision from the default of 6 decimal places is rare anyway, so as long as this behavior is documented,
  2539.     //    it seems okay for the moment.
  2540.     if (output_var)
  2541.     {
  2542.         // v1.0.45: Take a shortcut, which in the case of SYM_STRING/OPERAND/VAR avoids one memcpy
  2543.         // (into the deref buffer).  In some cases, this also saves from having to expand the deref buffer.
  2544.         output_var->Assign(result_token);
  2545.         goto normal_end_skip_output_var; // result_to_return is left at its default of "", though its value doesn't matter as long as it isn't NULL.
  2546.     }
  2547.  
  2548.     result_to_return = aTarget; // Set default.
  2549.     switch (result_token.symbol)
  2550.     {
  2551.     case SYM_INTEGER:
  2552.         // SYM_INTEGER and SYM_FLOAT will fit into our deref buffer because an earlier stage has already ensured
  2553.         // that the buffer is large enough to hold at least one number.  But a string/generic might not fit if it's
  2554.         // a concatenation and/or a large string returned from a called function.
  2555.         aTarget += strlen(ITOA64(result_token.value_int64, aTarget)) + 1; // Store in hex or decimal format, as appropriate.
  2556.         // Above: +1 because that's what callers want; i.e. the position after the terminator.
  2557.         goto normal_end_skip_output_var; // output_var was already checked higher above, so no need to consider it again.
  2558.     case SYM_FLOAT:
  2559.         // In case of float formats that are too long to be supported, use snprint() to restrict the length.
  2560.          // %f probably defaults to %0.6f.  %f can handle doubles in MSVC++.
  2561.         aTarget += snprintf(aTarget, MAX_FORMATTED_NUMBER_LENGTH + 1, g.FormatFloat, result_token.value_double) + 1; // +1 because that's what callers want; i.e. the position after the terminator.
  2562.         goto normal_end_skip_output_var; // output_var was already checked higher above, so no need to consider it again.
  2563.     case SYM_STRING:
  2564.     case SYM_OPERAND:
  2565.     case SYM_VAR: // SYM_VAR is somewhat unusual at this late a stage.
  2566.         // At this stage, we know the result has to go into our deref buffer because if a way existed to
  2567.         // avoid that, we would already have goto/returned higher above.  Also, at this stage,
  2568.         // the pending result can exist in one several places:
  2569.         // 1) Our deref buf (due to being a single-deref, a function's return value that was copied to the
  2570.         //    end of our buf because there was enough room, etc.)
  2571.         // 2) In a called function's deref buffer, namely sDerefBuf, which will be deleted by our caller
  2572.         //    shortly after we return to it.
  2573.         // 3) In an area of memory we alloc'd for lack of any better place to put it.
  2574.         if (result_token.symbol == SYM_VAR)
  2575.         {
  2576.             result = result_token.var->Contents();
  2577.             result_size = result_token.var->LengthIgnoreBinaryClip() + 1; // Ignore binary clipboard for anything other than ACT_ASSIGNEXPR (i.e. output_var!=NULL) because it's documented that except for certain features, binary clipboard variables are seen only up to the first binary zero (mostly to simplify the code).
  2578.         }
  2579.         else
  2580.         {
  2581.             result = result_token.marker;
  2582.             result_size = strlen(result) + 1;
  2583.         }
  2584.  
  2585.         // Notes about the macro below:
  2586.         // Space is needed for whichever of the following is greater (since only one of the following is in
  2587.         // the deref buf at any given time; i.e. they can share the space by being in it at different times):
  2588.         // 1) All the expression's literal strings/numbers and double-derefs (e.g. "Array%i%" as a string).
  2589.         //    Allowing room for this_arg.length plus a terminator seems enough for any conceivable
  2590.         //    expression, even worst-cases and malformatted syntax-error expressions. This is because
  2591.         //    every numeric literal or double-deref needs to have some kind of symbol or character
  2592.         //    between it and the next one or it would never have been recognized as a separate operand
  2593.         //    in the first place.  And the final item uses the final terminator provided via +1 below.
  2594.         // 2) Any numeric result (i.e. MAX_FORMATTED_NUMBER_LENGTH).  If the expression needs to store a
  2595.         //    string result, it will take care of expanding the deref buffer.
  2596.         #define EXPR_BUF_SIZE(raw_expr_len) (raw_expr_len < MAX_FORMATTED_NUMBER_LENGTH \
  2597.             ? MAX_FORMATTED_NUMBER_LENGTH : raw_expr_len) + 1 // +1 for the overall terminator.
  2598.  
  2599.         // If result is the empty string or a number, it should always fit because the size estimation
  2600.         // phase has ensured that capacity_of_our_buf_portion is large enough to hold those.
  2601.         // In addition, it doesn't matter if we already used target/aTarget for things higher above
  2602.         // because anything in there we're now done with, and memmove() vs. memcpy() later below
  2603.         // will allow overlap of the final result with intermediate results already in the buffer.
  2604.         size_t capacity_of_our_buf_portion;
  2605.         capacity_of_our_buf_portion = EXPR_BUF_SIZE(mArg[aArgIndex].length) + aExtraSize; // The initial amount of size available to write our final result.
  2606.         if (result_size > capacity_of_our_buf_portion)
  2607.         {
  2608.             // Do a simple expansion of our deref buffer to handle the fact that our actual result is bigger
  2609.             // than the size estimator could have calculated (due to a concatenation or a large string returned
  2610.             // from a called function).  This performs poorly but seems justified by the fact that it typically
  2611.             // happens only in extreme cases.
  2612.             size_t new_buf_size = aDerefBufSize + (result_size - capacity_of_our_buf_portion);
  2613.  
  2614.             // malloc() and free() are used instead of realloc() because in many cases, the overhead of
  2615.             // realloc()'s internal memcpy(entire contents) can be avoided because only part or
  2616.             // none of the contents needs to be copied (realloc's ability to do an in-place resize might
  2617.             // be unlikely for anything other than small blocks; see compiler's realloc.c):
  2618.             char *new_buf;
  2619.             if (   !(new_buf = (char *)malloc(new_buf_size))   )
  2620.             {
  2621.                 LineError(ERR_OUTOFMEM ERR_ABORT);
  2622.                 goto abort;
  2623.             }
  2624.             if (new_buf_size > LARGE_DEREF_BUF_SIZE)
  2625.                 ++sLargeDerefBufs; // And if the old deref buf was larger too, this value is decremented later below.
  2626.  
  2627.             // Copy only that portion of the old buffer that is in front of our portion of the buffer
  2628.             // because we no longer need our portion (except for result.marker if it happens to be
  2629.             // in the old buffer, but that is handled after this):
  2630.             size_t aTarget_offset = aTarget - aDerefBuf;
  2631.             if (aTarget_offset) // aDerefBuf has contents that must be preserved.
  2632.                 memcpy(new_buf, aDerefBuf, aTarget_offset); // This will also copy the empty string if the buffer first and only character is that.
  2633.             aTarget = new_buf + aTarget_offset;
  2634.             result_to_return = aTarget; // Update to reflect new value above.
  2635.             // NOTE: result_token.marker might extend too far to the right in our deref buffer and thus be
  2636.             // larger than capacity_of_our_buf_portion because other arg(s) exist in this line after ours
  2637.             // that will be using a larger total portion of the buffer than ours.  Thus, the following must be
  2638.             // done prior to free(), but memcpy() vs. memmove() is safe in any case:
  2639.             memcpy(aTarget, result, result_size); // Copy from old location to the newly allocated one.
  2640.  
  2641.             free(aDerefBuf); // Free our original buffer since it's contents are no longer needed.
  2642.             if (aDerefBufSize > LARGE_DEREF_BUF_SIZE)
  2643.                 --sLargeDerefBufs;
  2644.  
  2645.             // Now that the buffer has been enlarged, need to adjust any other pointers that pointed into
  2646.             // the old buffer:
  2647.             char *aDerefBuf_end = aDerefBuf + aDerefBufSize; // Point it to the character after the end of the old buf.
  2648.             for (i = 0; i < aArgIndex; ++i) // Adjust each item beneath ours (if any). Our own is not adjusted because we'll be returning the right address to our caller.
  2649.                 if (aArgDeref[i] >= aDerefBuf && aArgDeref[i] < aDerefBuf_end)
  2650.                     aArgDeref[i] = new_buf + (aArgDeref[i] - aDerefBuf); // Set for our caller.
  2651.             // The following isn't done because target isn't used anymore at this late a stage:
  2652.             //target = new_buf + (target - aDerefBuf);
  2653.             aDerefBuf = new_buf; // Must be the last step, since the old address is used above.  Set for our caller.
  2654.             aDerefBufSize = new_buf_size; // Set for our caller.
  2655.         }
  2656.         else // Deref buf is already large enough to fit the string.
  2657.             if (aTarget != result) // Currently, might be always true.
  2658.                 memmove(aTarget, result, result_size); // memmove() vs. memcpy() in this case, since source and dest might overlap (i.e. "target" may have been used to put temporary things into aTarget, but those things are no longer needed and now safe to overwrite).
  2659.         aTarget += result_size;
  2660.         goto normal_end_skip_output_var; // output_var was already checked higher above, so no need to consider it again.
  2661.  
  2662.     default: // Result contains a non-operand symbol such as an operator.
  2663.         goto abnormal_end;
  2664.     } // switch (result_token.symbol)
  2665.  
  2666. // ALL PATHS ABOVE SHOULD "GOTO".  TO CATCH BUGS, ANY THAT DON'T FALL INTO "ABORT" BELOW.
  2667. abort:
  2668.     // The callers of this function know that the value of aResult (which contains the reason
  2669.     // for early exit) should be considered valid/meaningful only if result_to_return is NULL.
  2670.     result_to_return = NULL; // Use NULL to inform our caller that this entire thread is to be terminated.
  2671.     aResult = FAIL; // Indicate reason to caller.
  2672.     goto normal_end_skip_output_var; // output_var is skipped as part of standard abort behavior.
  2673.  
  2674. abnormal_end: // Currently the same as normal_end; it's separate to improve readability.  When this happens, result_to_return is typically "" (unless the caller overrode that default).
  2675. //normal_end: // This isn't currently used, but is available for future-use and readability.
  2676.     // v1.0.45: ACT_ASSIGNEXPR relies on us to set the output_var (i.e. whenever it's ARG1's is_expression==true).
  2677.     // Our taking charge of output_var allows certain performance optimizations in other parts of this function,
  2678.     // such as avoiding excess memcpy's and malloc's during intermediate stages.
  2679.     if (output_var && result_to_return) // i.e. don't assign if NULL to preserve backward compatibility with scripts that rely on the old value being changed in cases where an expression fails (unlikely).
  2680.         output_var->Assign(result_to_return);
  2681.  
  2682. normal_end_skip_output_var:
  2683.     for (i = mem_count; i--;) // Free any temporary memory blocks that were used.  Using reverse order might reduce memory fragmentation a little (depending on implementation of malloc).
  2684.         free(mem[i]);
  2685.  
  2686.     return result_to_return;
  2687. }
  2688.  
  2689.  
  2690.  
  2691. ResultType Line::ExpandArgs(VarSizeType aSpaceNeeded, Var *aArgVar[])
  2692. // Caller should either provide both or omit both of the parameters.  If provided, it means
  2693. // caller already called GetExpandedArgSize for us.
  2694. // Returns OK, FAIL, or EARLY_EXIT.  EARLY_EXIT occurs when a function-call inside an expression
  2695. // used the EXIT command to terminate the thread.
  2696. {
  2697.     // The counterparts of sArgDeref and sArgVar kept on our stack to protect them from recursion caused by
  2698.     // the calling of functions in the script:
  2699.     char *arg_deref[MAX_ARGS];
  2700.     Var *arg_var[MAX_ARGS];
  2701.     int i;
  2702.  
  2703.     // Make two passes through this line's arg list.  This is done because the performance of
  2704.     // realloc() is worse than doing a free() and malloc() because the former often does a memcpy()
  2705.     // in addition to the latter's steps.  In addition, realloc() as much as doubles the memory
  2706.     // load on the system during the brief time that both the old and the new blocks of memory exist.
  2707.     // First pass: determine how much space will be needed to do all the args and allocate
  2708.     // more memory if needed.  Second pass: dereference the args into the buffer.
  2709.  
  2710.     // First pass. It takes into account the same things as 2nd pass.
  2711.     size_t space_needed;
  2712.     if (aSpaceNeeded == VARSIZE_ERROR)
  2713.     {
  2714.         space_needed = GetExpandedArgSize(true, arg_var);
  2715.         if (space_needed == VARSIZE_ERROR)
  2716.             return FAIL;  // It will have already displayed the error.
  2717.     }
  2718.     else // Caller already determined it.
  2719.     {
  2720.         space_needed = aSpaceNeeded;
  2721.         for (i = 0; i < mArgc; ++i) // Copying only the actual/used elements is probably faster than using memcpy to copy both entire arrays.
  2722.             arg_var[i] = aArgVar[i]; // Init to values determined by caller, which helps performance if any of the args are dynamic variables.
  2723.     }
  2724.  
  2725.     if (space_needed > g_MaxVarCapacity)
  2726.         // Dereferencing the variables in this line's parameters would exceed the allowed size of the temp buffer:
  2727.         return LineError(ERR_MEM_LIMIT_REACHED);
  2728.  
  2729.     // Only allocate the buf at the last possible moment,
  2730.     // when it's sure the buffer will be used (improves performance when only a short
  2731.     // script with no derefs is being run):
  2732.     if (space_needed > sDerefBufSize)
  2733.     {
  2734.         // KNOWN LIMITATION: The memory utilization of *recursive* user-defined functions is rather high because
  2735.         // of the size of DEREF_BUF_EXPAND_INCREMENT, which is used to create a new deref buffer for each
  2736.         // layer of recursion.  So if a UDF recurses deeply, say 100 layers, about 1600 MB (16KB*100) of
  2737.         // memory would be temporarily allocated, which in a worst-case scenario would cause swapping and
  2738.         // kill performance.  Perhaps the best solution to this is to dynamically change the size of
  2739.         // DEREF_BUF_EXPAND_INCREMENT (via a new global variable) in the expression evaluation section that
  2740.         // detects that a UDF has another instance of itself on the call stack.  To ensure proper collapse-back
  2741.         // out of nested udfs and threads, the old value should be backed up, the new smaller increment set,
  2742.         // then the old size should be passed to FreeAndRestoreFunctionVars() so that it can restore it.
  2743.         // However, given the rarity of deep recursion, this doesn't seem worth the extra code size and loss of
  2744.         // performance.
  2745.         size_t increments_needed = space_needed / DEREF_BUF_EXPAND_INCREMENT;
  2746.         if (space_needed % DEREF_BUF_EXPAND_INCREMENT)  // Need one more if above division truncated it.
  2747.             ++increments_needed;
  2748.         size_t new_buf_size = increments_needed * DEREF_BUF_EXPAND_INCREMENT;
  2749.         if (sDerefBuf)
  2750.         {
  2751.             // Do a free() and malloc(), which should be far more efficient than realloc(), especially if
  2752.             // there is a large amount of memory involved here (realloc's ability to do an in-place resize
  2753.             // might be unlikely for anything other than small blocks; see compiler's realloc.c):
  2754.             free(sDerefBuf);
  2755.             if (sDerefBufSize > LARGE_DEREF_BUF_SIZE)
  2756.                 --sLargeDerefBufs;
  2757.         }
  2758.         if (   !(sDerefBuf = (char *)malloc(new_buf_size))   )
  2759.         {
  2760.             // Error msg was formerly: "Ran out of memory while attempting to dereference this line's parameters."
  2761.             sDerefBufSize = 0;  // Reset so that it can make another attempt, possibly smaller, next time.
  2762.             return LineError(ERR_OUTOFMEM ERR_ABORT); // Short msg since so rare.
  2763.         }
  2764.         sDerefBufSize = new_buf_size;
  2765.         if (sDerefBufSize > LARGE_DEREF_BUF_SIZE)
  2766.             ++sLargeDerefBufs;
  2767.     }
  2768.  
  2769.     // Always init our_buf_marker even if zero iterations, because we want to enforce
  2770.     // the fact that its prior contents become invalid once we're called.
  2771.     // It's also necessary due to the fact that all the old memory is discarded by
  2772.     // the above if more space was needed to accommodate this line.
  2773.     char *our_buf_marker = sDerefBuf;  // Prior contents of buffer will be overwritten in any case.
  2774.  
  2775.     // From this point forward, must not refer to sDerefBuf as our buffer since it might have been
  2776.     // given a new memory area by an expression's function-call within this line.  In other words,
  2777.     // our_buf_marker is our recursion layer's buffer, but not necessarily sDerefBuf.  To enforce
  2778.     // that, and keep responsibility here rather than in ExpandExpression(), set sDerefBuf to NULL
  2779.     // so that the zero or more calls to ExpandExpression() made in the loop below (each of which will
  2780.     // in turn call zero or more user-defined functions) will allocate and use a single new deref
  2781.     // buffer if any of them need it (they all share a single deref buffer because each UDF-call
  2782.     // in a particular expression of the current line creates a buf only if necessary, and it won't
  2783.     // be necessary if some prior UDF of this same expression or line already created a deref buffer
  2784.     // "above" ours because our layer here is the only one who ever frees that upper/extra buffer).
  2785.     // Note that it is not possible for a new quasi-thread to directly interrupt ExpandArgs() because
  2786.     // ExpandArgs() never calls MsgSleep().  Therefore, each ExpandArgs() layer on the call-stack
  2787.     // is safe from interrupting threads overwriting its deref buffer.  It's true that a call to a
  2788.     // script function will usually result in MsgSleep(), and thus allow interruptions, but those
  2789.     // interruptions would hit some other deref buffer, not that of our layer.
  2790.     char *our_deref_buf = sDerefBuf; // For detecting whether ExpandExpression() caused a new buffer to be created.
  2791.     size_t our_deref_buf_size = sDerefBufSize;
  2792.     SET_S_DEREF_BUF(NULL, 0);
  2793.  
  2794.     ResultType result, result_to_return = OK;  // Set default return value.
  2795.     Var *the_only_var_of_this_arg;
  2796.  
  2797.     if (!mArgc)            // v1.0.45: Required by some commands that can have zero parameters (such as Random and
  2798.         sArgVar[0] = NULL; // PixelSearch), even if it's just to allow their output-var(s) to be omitted.  This allows OUTPUT_VAR to be used without any need to check mArgC.
  2799.     else
  2800.     {
  2801.         size_t extra_size = our_deref_buf_size - space_needed;
  2802.         for (i = 0; i < mArgc; ++i) // Second pass.  For each arg:
  2803.         {
  2804.             ArgStruct &this_arg = mArg[i]; // For performance and convenience.
  2805.  
  2806.             // Load-time routines have already ensured that an arg can be an expression only if
  2807.             // it's not an input or output var.
  2808.             if (this_arg.is_expression)
  2809.             {
  2810.                 // v1.0.45:
  2811.                 // Make ARGVAR1 (OUTPUT_VAR) temporarily valid (the entire array is made valid only later, near the
  2812.                 // bottom of this function).  This helps the performance of ACT_ASSIGNEXPR by avoiding the need
  2813.                 // resolve a dynamic output variable like "Array%i% := (Expr)" twice: once in GetExpandedArgSize
  2814.                 // and again in ExpandExpression()).
  2815.                 *sArgVar = *arg_var; // Shouldn't need to be backed up or restored because no one beneath us on the call stack should be using it; only things that go on top of us might overwrite it, so ExpandExpr() must be sure to copy this out before it launches any script-functions.
  2816.                 // In addition to producing its return value, ExpandExpression() will alter our_buf_marker
  2817.                 // to point to the place in our_deref_buf where the next arg should be written.
  2818.                 // In addition, in some cases it will alter some of the other parameters that are arrays or
  2819.                 // that are passed by-ref.  Finally, it might temporarily use parts of the buffer beyond
  2820.                 // extra_size plus what the size estimator provided for it, so we should be sure here that
  2821.                 // everything in our_deref_buf to the right of our_buf_marker is available to it as temporary memory.
  2822.                 // Note: It doesn't seem worthwhile to enhance ExpandExpression to give us back a variable
  2823.                 // for use in arg_var[] (for performance) because only rarely does an expression yield
  2824.                 // a variable other than some function's local variable (and a local's contents are no
  2825.                 // longer valid due to having been freed after the call [unless it's static]).
  2826.                 arg_deref[i] = ExpandExpression(i, result, our_buf_marker, our_deref_buf
  2827.                     , our_deref_buf_size, arg_deref, extra_size);
  2828.                 extra_size = 0; // See comment below.
  2829.                 // v1.0.46.01: The whole point of passing extra_size is to allow an expression to write
  2830.                 // a large string to the deref buffer without having to expand it (i.e. if there happens to
  2831.                 // be extra room in it that won't be used by ANY arg, including ones after THIS expression).
  2832.                 // Since the expression just called above might have used some/all of the extra size,
  2833.                 // the line above prevents subsequent expressions in this line from getting any extra size.
  2834.                 // It's pretty rare to have more than one expression in a line anyway, and even when there
  2835.                 // is there's hardly ever a need for the extra_size.  As an alternative to setting it to
  2836.                 // zero, above could check how much the expression wrote to the buffer (by comparing our_buf_marker
  2837.                 // before and after the call above), and compare that to how much space was reserved for this
  2838.                 // particular arg/expression (which is currently a standard formula for expressions).
  2839.                 if (!arg_deref[i])
  2840.                 {
  2841.                     // A script-function-call inside the expression returned EARLY_EXIT or FAIL.  Report "result"
  2842.                     // to our caller (otherwise, the contents of "result" should be ignored since they're undefined).
  2843.                     result_to_return = result;
  2844.                     goto end;
  2845.                 }
  2846.                 continue;
  2847.             }
  2848.  
  2849.             if (this_arg.type == ARG_TYPE_OUTPUT_VAR)  // Don't bother wasting the mem to deref output var.
  2850.             {
  2851.                 // In case its "dereferenced" contents are ever directly examined, set it to be
  2852.                 // the empty string.  This also allows the ARG to be passed a dummy param, which
  2853.                 // makes things more convenient and maintainable in other places:
  2854.                 arg_deref[i] = "";
  2855.                 continue;
  2856.             }
  2857.  
  2858.             // arg_var[i] was previously set by GetExpandedArgSize() so that we don't have to determine its
  2859.             // value again:
  2860.             if (   !(the_only_var_of_this_arg = arg_var[i])   ) // Arg isn't an input var or singled isolated deref.
  2861.             {
  2862.                 #define NO_DEREF (!ArgHasDeref(i + 1))
  2863.                 if (NO_DEREF)
  2864.                 {
  2865.                     arg_deref[i] = this_arg.text;  // Point the dereferenced arg to the arg text itself.
  2866.                     continue;  // Don't need to use the deref buffer in this case.
  2867.                 }
  2868.             }
  2869.  
  2870.             // Check the value of the_only_var_of_this_arg again in case the above changed it:
  2871.             if (the_only_var_of_this_arg) // This arg resolves to only a single, naked var.
  2872.             {
  2873.                 switch(ArgMustBeDereferenced(the_only_var_of_this_arg, i, arg_var)) // Yes, it was called by GetExpandedArgSize() too, but a review shows it's difficult to avoid this without being worse than the disease (10/22/2006).
  2874.                 {
  2875.                 case CONDITION_FALSE:
  2876.                     // This arg contains only a single dereference variable, and no
  2877.                     // other text at all.  So rather than copy the contents into the
  2878.                     // temp buffer, it's much better for performance (especially for
  2879.                     // potentially huge variables like %clipboard%) to simply set
  2880.                     // the pointer to be the variable itself.  However, this can only
  2881.                     // be done if the var is the clipboard or a non-environment
  2882.                     // normal var (since zero-length normal vars need to be fetched via
  2883.                     // GetEnvironmentVariable() when g_NoEnv==false).
  2884.                     // Update: Changed it so that it will deref the clipboard if it contains only
  2885.                     // files and no text, so that the files will be transcribed into the deref buffer.
  2886.                     // This is because the clipboard object needs a memory area into which to write
  2887.                     // the filespecs it translated:
  2888.                     arg_deref[i] = the_only_var_of_this_arg->Contents();
  2889.                     break;
  2890.                 case CONDITION_TRUE:
  2891.                     // the_only_var_of_this_arg is either a reserved var or a normal var of that is also
  2892.                     // an environment var (for which GetEnvironmentVariable() is called for), or is used
  2893.                     // again in this line as an output variable.  In all these cases, it must
  2894.                     // be expanded into the buffer rather than accessed directly:
  2895.                     arg_deref[i] = our_buf_marker; // Point it to its location in the buffer.
  2896.                     our_buf_marker += the_only_var_of_this_arg->Get(our_buf_marker) + 1; // +1 for terminator.
  2897.                     break;
  2898.                 default: // FAIL should be the only other possibility.
  2899.                     result_to_return = FAIL; // ArgMustBeDereferenced() will already have displayed the error.
  2900.                     goto end;
  2901.                 }
  2902.             }
  2903.             else // The arg must be expanded in the normal, lower-performance way.
  2904.             {
  2905.                 arg_deref[i] = our_buf_marker; // Point it to its location in the buffer.
  2906.                 if (   !(our_buf_marker = ExpandArg(our_buf_marker, i))   ) // Expand the arg into that location.
  2907.                 {
  2908.                     result_to_return = FAIL; // ExpandArg() will have already displayed the error.
  2909.                     goto end;
  2910.                 }
  2911.             }
  2912.         } // for each arg.
  2913.  
  2914.         // IT'S NOT SAFE to do the following until the above loop FULLY completes because any calls made above to
  2915.         // ExpandExpression() might call functions, which in turn might result in a recursive call to ExpandArgs(),
  2916.         // which in turn might change the values in the static arrays sArgDeref and sArgVar.
  2917.         // Also, only when the loop ends normally is the following needed, since otherwise it's a failure condition.
  2918.         // Now that any recursive calls to ExpandArgs() above us on the stack have collapsed back to us, it's
  2919.         // safe to set the args of this command for use by our caller, to whom we're about to return.
  2920.         for (i = 0; i < mArgc; ++i) // Copying actual/used elements is probably faster than using memcpy to copy both entire arrays.
  2921.         {
  2922.             sArgDeref[i] = arg_deref[i];
  2923.             sArgVar[i] = arg_var[i];
  2924.         }
  2925.     } // mArgc > 0
  2926.  
  2927.     // v1.0.40.02: The following loop was added to avoid the need for the ARGn macros to provide an empty
  2928.     // string when mArgc was too small (indicating that the parameter is absent).  This saves quite a bit
  2929.     // of code size.  Also, the slight performance loss caused by it is partially made up for by the fact
  2930.     // that all the other sections don't need to check mArgc anymore.
  2931.     // Benchmarks show that it doesn't help performance to try to tweak this with a pre-check such as
  2932.     // "if (mArgc < max_params)":
  2933.     int max_params = g_act[mActionType].MaxParams; // Resolve once for performance.
  2934.     for (i = mArgc; i < max_params; ++i) // For performance, this only does the actual max args for THIS command, not MAX_ARGS.
  2935.         sArgDeref[i] = "";
  2936.         // But sArgVar isn't done (since it's more rarely used) except sArgVar[0] = NULL higher above.
  2937.         // Therefore, users of sArgVar must check mArgC if they have any doubt how many args are present in
  2938.         // the script line (this is now enforced via macros).
  2939.  
  2940.     // When the main/large loop above ends normally, it falls into the label below and uses the original/default
  2941.     // value of "result_to_return".
  2942.  
  2943. end:
  2944.     // As of v1.0.31, there can be multiple deref buffers simultaneously if one or more called functions
  2945.     // requires a deref buffer of its own (separate from ours).  In addition, if a called function is
  2946.     // interrupted by a new thread before it finishes, the interrupting thread will also use the
  2947.     // new/separate deref buffer.  To minimize the amount of memory used in such cases cases,
  2948.     // each line containing one or more expression with one or more function call (rather than each
  2949.     // function call) will get up to one deref buffer of its own (i.e. only if its function body contains
  2950.     // commands that actually require a second deref buffer).  This is achieved by saving sDerefBuf's
  2951.     // pointer and setting sDerefBuf to NULL, which effectively makes the original deref buffer private
  2952.     // until the line that contains the function-calling expressions finishes completely.
  2953.     // Description of recursion and usage of multiple deref buffers:
  2954.     // 1) ExpandArgs() receives a line with one or more expressions containing one or more calls to user functions.
  2955.     // 2) Worst-case: those function-calls create a new sDerefBuf automatically via us having set sDerefBuf to NULL.
  2956.     // 3) Even worse, the bodies of those functions call other functions, which ExpandArgs() receives, resulting in
  2957.     //    a recursive leap back to step #1.
  2958.     // So the above shows how any number of new deref buffers can be created.  But that's okay as long as the
  2959.     // recursion collapses in an orderly manner (or the program exits, in which case the OS frees all its memory
  2960.     // automatically).  This is because prior to returning, each recursion layer properly frees any extra deref
  2961.     // buffer it was responsible for creating.  It only has to free at most one such buffer because each layer of
  2962.     // ExpandArgs() on the call-stack can never be blamed for creating more than one extra buffer.
  2963.     if (our_deref_buf)
  2964.     {
  2965.         // Must always restore the original buffer, not keep the new one, because our caller needs
  2966.         // the arg_deref addresses, which point into the original buffer.
  2967.         if (sDerefBuf)
  2968.         {
  2969.             free(sDerefBuf);
  2970.             if (sDerefBufSize > LARGE_DEREF_BUF_SIZE)
  2971.                 --sLargeDerefBufs;
  2972.         }
  2973.         SET_S_DEREF_BUF(our_deref_buf, our_deref_buf_size);
  2974.     }
  2975.     //else the original buffer is NULL, so keep any new sDerefBuf that might have been created (should
  2976.     // help avg-case performance).
  2977.  
  2978.     // For v1.0.31, this is no done right before returning so that any script function calls
  2979.     // made by our calls to ExpandExpression() will now be done.  There might still be layers
  2980.     // of ExpandArgs() beneath us on the call-stack, which is okay since they will keep the
  2981.     // largest of the two available deref bufs (as described above) and thus they should
  2982.     // reset the timer below right before they collapse/return.  
  2983.     // (Re)set the timer unconditionally so that it starts counting again from time zero.
  2984.     // In other words, we only want the timer to fire when the large deref buffer has been
  2985.     // unused/idle for a straight 10 seconds.  There is no danger of this timer freeing
  2986.     // the deref buffer at a critical moment because:
  2987.     // 1) The timer is reset with each call to ExpandArgs (this function);
  2988.     // 2) If our ExpandArgs() recursion layer takes a long time to finish, messages
  2989.     //    won't be checked and thus the timer can't fire because it relies on the msg loop.
  2990.     // 3) If our ExpandArgs() recursion layer launches function-calls in ExpandExpression(),
  2991.     //    those calls will call ExpandArgs() recursively and reset the timer if its
  2992.     //    buffer (not necessarily the original buffer somewhere on the call-stack) is large
  2993.     //    enough.  In light of this, there is a chance that the timer might execute and free
  2994.     //    a deref buffer other than the one it was originally intended for.  But in real world
  2995.     //    scenarios, that seems rare.  In addition, the consequences seem to be limited to
  2996.     //    some slight memory inefficiency.
  2997.     // It could be aruged that the timer should only be activated when a hypothetical static
  2998.     // var sLayersthat we maintain here indicates that we're the only layer.  However, if that
  2999.     // were done and the launch of a script function creates (directly or through thread
  3000.     // interruption, indirectly) a large deref buffer, and that thread is waiting for something
  3001.     // such as WinWait, that large deref buffer would never get freed.
  3002.     #define SET_DEREF_TIMER(aTimeoutValue) g_DerefTimerExists = SetTimer(g_hWnd, TIMER_ID_DEREF, aTimeoutValue, DerefTimeout);
  3003.     if (sDerefBufSize > LARGE_DEREF_BUF_SIZE)
  3004.         SET_DEREF_TIMER(10000) // Reset the timer right before the deref buf is possibly about to become idle.
  3005.  
  3006.     return result_to_return;
  3007. }
  3008.  
  3009.     
  3010.  
  3011. VarSizeType Line::GetExpandedArgSize(bool aCalcDerefBufSize, Var *aArgVar[])
  3012. // Returns the size, or VARSIZE_ERROR if there was a problem.
  3013. // This function can return a size larger than what winds up actually being needed
  3014. // (e.g. caused by ScriptGetCursor()), so our callers should be aware that that can happen.
  3015. {
  3016.     int i;
  3017.     VarSizeType space_needed;
  3018.     Var *the_only_var_of_this_arg;
  3019.     ResultType result;
  3020.  
  3021.     // Note: the below loop is similar to the one in ExpandArgs(), so the two should be maintained together:
  3022.     for (i = 0, space_needed = 0; i < mArgc; ++i) // FOR EACH ARG:
  3023.     {
  3024.         ArgStruct &this_arg = mArg[i]; // For performance and convenience.
  3025.  
  3026.         // Accumulate the total of how much space we will need.
  3027.         if (this_arg.type == ARG_TYPE_OUTPUT_VAR)  // These should never be included in the space calculation.
  3028.         {
  3029.             if (mActionType != ACT_ASSIGN) // PerformAssign() already resolved its output-var, so don't do it again here.
  3030.             {
  3031.                 if (   !(aArgVar[i] = ResolveVarOfArg(i))   ) // v1.0.45: Resolve output variables too, which eliminates a ton of calls to ResolveVarOfArg() in various other functions.  This helps code size more than performance.
  3032.                     return VARSIZE_ERROR;  // The above will have already displayed the error.
  3033.             }
  3034.             continue;
  3035.         }
  3036.         // Otherwise, set default aArgVar[] (above took care of setting aArgVar[] for itself).
  3037.         aArgVar[i] = NULL;
  3038.  
  3039.         if (this_arg.is_expression)
  3040.         {
  3041.             space_needed += EXPR_BUF_SIZE(this_arg.length); // See comments at macro definition.
  3042.             continue;
  3043.         }
  3044.  
  3045.         // Always do this check before attempting to traverse the list of dereferences, since
  3046.         // such an attempt would be invalid in this case:
  3047.         the_only_var_of_this_arg = NULL;
  3048.         if (this_arg.type == ARG_TYPE_INPUT_VAR) // Previous stage has ensured that arg can't be an expression if it's an input var.
  3049.             if (   !(the_only_var_of_this_arg = ResolveVarOfArg(i, false))   )
  3050.                 return VARSIZE_ERROR;  // The above will have already displayed the error.
  3051.  
  3052.         if (!the_only_var_of_this_arg) // It's not an input var.
  3053.         {
  3054.             if (NO_DEREF)
  3055.             {
  3056.                 if (!aCalcDerefBufSize) // i.e. we want the total size of what the args resolve to.
  3057.                     space_needed += this_arg.length + 1;  // +1 for the zero terminator.
  3058.                 // else don't increase space_needed, even by 1 for the zero terminator, because
  3059.                 // the terminator isn't needed if the arg won't exist in the buffer at all.
  3060.                 continue;
  3061.             }
  3062.             // Now we know it has at least one deref.  If the second deref's marker is NULL,
  3063.             // the first is the only deref in this arg.  UPDATE: The following will return
  3064.             // false for function calls since they are always followed by a set of parentheses
  3065.             // (empty or otherwise), thus they will never be seen as isolated by it:
  3066.             #define SINGLE_ISOLATED_DEREF (!this_arg.deref[1].marker\
  3067.                 && this_arg.deref[0].length == this_arg.length) // and the arg contains no literal text
  3068.             if (SINGLE_ISOLATED_DEREF) // This also ensures the deref isn't a function-call.  10/25/2006: It might be possible to avoid the need for detecting SINGLE_ISOLATED_DEREF by transforming them into INPUT_VARs at loadtime.  I almost finished such a mod but the testing and complications with things like ListLines didn't seem worth the tiny benefit.
  3069.                 the_only_var_of_this_arg = this_arg.deref[0].var;
  3070.         }
  3071.         if (the_only_var_of_this_arg) // i.e. check it again in case the above block changed the value.
  3072.         {
  3073.             // This is set for our caller so that it doesn't have to call ResolveVarOfArg() again, which
  3074.             // would a performance hit if this variable is dynamically built and thus searched for at runtime:
  3075.             aArgVar[i] = the_only_var_of_this_arg; // For now, this is done regardless of whether it must be dereferenced.
  3076.             if (aCalcDerefBufSize) // In this case, caller doesn't want its size unconditionally included, but instead only if certain conditions are met.
  3077.             {
  3078.                 if (   !(result = ArgMustBeDereferenced(the_only_var_of_this_arg, i, aArgVar))   )
  3079.                     return VARSIZE_ERROR;
  3080.                 if (result == CONDITION_FALSE)
  3081.                     continue;
  3082.                 //else the size of this arg is always included, so fall through to below.
  3083.             }
  3084.             //else caller wanted it's size unconditionally included, so continue on to below.
  3085.             space_needed += the_only_var_of_this_arg->Get() + 1;  // +1 for the zero terminator.
  3086.             // NOTE: Get() (with no params) can retrieve a size larger that what winds up actually
  3087.             // being needed, so our callers should be aware that that can happen.
  3088.             continue;
  3089.         }
  3090.  
  3091.         // Otherwise: This arg has more than one deref, or a single deref with some literal text around it.
  3092.         space_needed += this_arg.length + 1; // +1 for this arg's zero terminator in the buffer.
  3093.         if (this_arg.deref) // There's at least one deref.
  3094.         {
  3095.             for (DerefType *deref = this_arg.deref; deref->marker; ++deref)
  3096.             {
  3097.                 // Replace the length of the deref's literal text with the length of its variable's contents:
  3098.                 space_needed -= deref->length;
  3099.                 if (!deref->is_function)
  3100.                     space_needed += deref->var->Get(); // If an environment var, Get() will yield its length.
  3101.                 //else it's a function-call's function name, in which case it's length is effectively zero since
  3102.                 // the function name never gets copied into the deref buffer during ExpandExpression().
  3103.             }
  3104.         }
  3105.     } // For each arg.
  3106.  
  3107.     return space_needed;
  3108. }
  3109.  
  3110.  
  3111.  
  3112. ResultType Line::ArgMustBeDereferenced(Var *aVar, int aArgIndex, Var *aArgVar[]) // 10/22/2006: __forceinline didn't help enough to be worth the added code size of having two instances.
  3113. // Shouldn't be called only for args of type ARG_TYPE_OUTPUT_VAR because they never need to be dereferenced.
  3114. // aArgVar[] is used for performance; it's assumed to contain valid items only up to aArgIndex, not beyond
  3115. // (since normally output vars lie to the left of all input vars, so it doesn't seem worth doing anything
  3116. // more complicated).
  3117. // Returns CONDITION_TRUE, CONDITION_FALSE, or FAIL.
  3118. {
  3119.     if (mActionType == ACT_SORT) // See PerformSort() for why it's always dereferenced.
  3120.         return CONDITION_TRUE;
  3121.     aVar = aVar->ResolveAlias(); // Helps performance, but also necessary to accurately detect a match further below.
  3122.     if (aVar->Type() == VAR_CLIPBOARD)
  3123.         // Even if the clipboard is both an input and an output var, it still
  3124.         // doesn't need to be dereferenced into the temp buffer because the
  3125.         // clipboard has two buffers of its own.  The only exception is when
  3126.         // the clipboard has only files on it, in which case those files need
  3127.         // to be converted into plain text:
  3128.         return CLIPBOARD_CONTAINS_ONLY_FILES ? CONDITION_TRUE : CONDITION_FALSE;
  3129.     if (aVar->Type() != VAR_NORMAL || (!g_NoEnv && !aVar->Length()) || aVar == g_ErrorLevel) // v1.0.43.08: Added g_NoEnv.
  3130.         // Reserved vars must always be dereferenced due to their volatile nature.
  3131.         // When g_NoEnv==false, normal vars of length zero are dereferenced because they might exist
  3132.         // as system environment variables, whose contents are also potentially volatile (i.e. they
  3133.         // are sometimes changed by outside forces).
  3134.         // As of v1.0.25.12, g_ErrorLevel is always dereferenced also so that a command that sets ErrorLevel
  3135.         // can itself use ErrorLevel as in this example: StringReplace, EndKey, ErrorLevel, EndKey:
  3136.         return CONDITION_TRUE;
  3137.  
  3138.     // Before doing the below, the checks above must be done to ensure it's VAR_NORMAL.  Otherwise, things like
  3139.     // the following won't work: StringReplace, o, A_ScriptFullPath, xxx
  3140.     // v1.0.45: The following check improves performance slightly by avoiding the loop further below in cases
  3141.     // where it's known that a command either doesn't have an output_var or can tolerate the output_var's
  3142.     // contents being at the same address as that of one or more of the input-vars.  For example, the commands
  3143.     // StringRight/Left and similar can tolerate the same address because they always produce a string whose
  3144.     // length is less-than-or-equal to the input-string, thus Assign() will never need to free/realloc the
  3145.     // output-var prior to assigning the input-var's contents to it (whose contents are the same as output-var).
  3146.     if (!(g_act[mActionType].MaxParamsAu2WithHighBit & 0x80)) // Commands that have this bit don't need final check
  3147.         return CONDITION_FALSE;                               // further below (though they do need the ones above).
  3148.  
  3149.     // Since the above didn't return, we know that this is a NORMAL input var that isn't an
  3150.     // environment variable.  Such input vars only need to be dereferenced if they are also
  3151.     // used as an output var by the current script line:
  3152.     Var *output_var;
  3153.     for (int i = 0; i < mArgc; ++i)
  3154.         if (i != aArgIndex && mArg[i].type == ARG_TYPE_OUTPUT_VAR)
  3155.         {
  3156.             if (   !(output_var = (i < aArgIndex) ? aArgVar[i] : ResolveVarOfArg(i, false))   ) // aArgVar: See top of this function for comments.
  3157.                 return FAIL;  // It will have already displayed the error.
  3158.             if (output_var->ResolveAlias() == aVar)
  3159.                 return CONDITION_TRUE;
  3160.         }
  3161.     // Otherwise:
  3162.     return CONDITION_FALSE;
  3163. }
  3164.  
  3165.  
  3166.  
  3167. char *Line::ExpandArg(char *aBuf, int aArgIndex, Var *aArgVar) // 10/2/2006: Doesn't seem worth making it inline due to more complexity than expected.  It would also increase code size without being likely to help performance much.
  3168. // Caller must ensure that aArgVar is the variable of the aArgIndex arg when it's of type ARG_TYPE_INPUT_VAR.
  3169. // Caller must be sure not to call this for an arg that's marked as an expression, since
  3170. // expressions are handled by a different function.  Similarly, it must ensure that none
  3171. // of this arg's deref's are function-calls, i.e. that deref->is_function is always false.
  3172. // Caller must ensure that aBuf is large enough to accommodate the translation
  3173. // of the Arg.  No validation of above params is done, caller must do that.
  3174. // Returns a pointer to the char in aBuf that occurs after the zero terminator
  3175. // (because that's the position where the caller would normally resume writing
  3176. // if there are more args, since the zero terminator must normally be retained
  3177. // between args).
  3178. {
  3179.     ArgStruct &this_arg = mArg[aArgIndex]; // For performance and convenience.
  3180. #ifdef _DEBUG
  3181.     // This should never be called if the given arg is an output var, so flag that in DEBUG mode:
  3182.     if (this_arg.type == ARG_TYPE_OUTPUT_VAR)
  3183.     {
  3184.         LineError("DEBUG: ExpandArg() was called to expand an arg that contains only an output variable.");
  3185.         return NULL;
  3186.     }
  3187. #endif
  3188.  
  3189.     if (aArgVar)
  3190.         // +1 so that we return the position after the terminator, as required.
  3191.         return aBuf += aArgVar->Get(aBuf) + 1;
  3192.  
  3193.     char *this_marker, *pText = this_arg.text;  // Start at the begining of this arg's text.
  3194.     if (this_arg.deref) // There's at least one deref.
  3195.     {
  3196.         for (DerefType *deref = this_arg.deref  // Start off by looking for the first deref.
  3197.             ; deref->marker; ++deref)  // A deref with a NULL marker terminates the list.
  3198.         {
  3199.             // FOR EACH DEREF IN AN ARG (if we're here, there's at least one):
  3200.             // Copy the chars that occur prior to deref->marker into the buffer:
  3201.             for (this_marker = deref->marker; pText < this_marker; *aBuf++ = *pText++); // memcpy() is typically slower for small copies like this, at least on some hardware.
  3202.             // Now copy the contents of the dereferenced var.  For all cases, aBuf has already
  3203.             // been verified to be large enough, assuming the value hasn't changed between the
  3204.             // time we were called and the time the caller calculated the space needed.
  3205.             aBuf += deref->var->Get(aBuf); // Caller has ensured that deref->is_function==false
  3206.             // Finally, jump over the dereference text. Note that in the case of an expression, there might not
  3207.             // be any percent signs within the text of the dereference, e.g. x + y, not %x% + %y%.
  3208.             pText += deref->length;
  3209.         }
  3210.     }
  3211.     // Copy any chars that occur after the final deref into the buffer:
  3212.     for (; *pText; *aBuf++ = *pText++); // memcpy() is typically slower for small copies like this, at least on some hardware.
  3213.     // Terminate the buffer, even if nothing was written into it:
  3214.     *aBuf++ = '\0';
  3215.     return aBuf; // Returns the position after the terminator.
  3216. }
  3217.